136 lines
4.3 KiB
Python

from rest_framework import serializers
from api.v1.employees.serializers import EmployeeBriefSerializer
from tasks.automation.schema import (
AutomationSchemaError,
validate_automation_payload,
)
from tasks.models import (
TaskAutomation,
TaskAutomationKind,
TaskAutomationRun,
TaskBoard,
)
class TaskAutomationRunSerializer(serializers.ModelSerializer):
automation_name = serializers.CharField(source="automation.name", read_only=True)
task_title = serializers.CharField(source="task.title", read_only=True)
actor = EmployeeBriefSerializer(read_only=True)
class Meta:
model = TaskAutomationRun
fields = [
"id",
"automation",
"automation_name",
"task",
"task_title",
"trigger_activity",
"actor",
"source",
"status",
"context",
"actions_log",
"error",
"started_at",
"finished_at",
]
read_only_fields = fields
class TaskAutomationSerializer(serializers.ModelSerializer):
"""Validate shared automation rules exposed to authenticated task users.
``can_manage`` intentionally mirrors the temporary broad API permission. It
should use the dedicated automation permission once that role is introduced.
"""
created_by = EmployeeBriefSerializer(read_only=True)
boards = serializers.PrimaryKeyRelatedField(
queryset=TaskBoard.objects.filter(is_archived=False),
many=True,
required=False,
)
runs_count = serializers.IntegerField(read_only=True, default=0)
can_manage = serializers.SerializerMethodField()
class Meta:
model = TaskAutomation
fields = [
"id",
"name",
"description",
"kind",
"trigger",
"conditions",
"actions",
"schedule_config",
"applies_to_all_boards",
"boards",
"is_active",
"stop_on_error",
"position",
"created_by",
"last_run_at",
"runs_count",
"can_manage",
"created_at",
"updated_at",
]
read_only_fields = [
"id",
"created_by",
"last_run_at",
"runs_count",
"can_manage",
"created_at",
"updated_at",
]
def get_can_manage(self, obj) -> bool:
user = getattr(self.context.get("request"), "user", None)
return bool(user and user.is_authenticated)
def validate_name(self, value):
name = value.strip()
if not name:
raise serializers.ValidationError("Введите название автоматизации.")
return name
def validate(self, attrs):
attrs = super().validate(attrs)
instance = self.instance
kind = attrs.get("kind", getattr(instance, "kind", TaskAutomationKind.EVENT))
trigger = attrs.get("trigger", getattr(instance, "trigger", "task_updated"))
conditions = attrs.get("conditions", getattr(instance, "conditions", {}))
actions = attrs.get("actions", getattr(instance, "actions", []))
schedule_config = attrs.get(
"schedule_config",
getattr(instance, "schedule_config", {}),
)
try:
normalized = validate_automation_payload(
kind=kind,
trigger=trigger,
conditions=conditions,
actions=actions,
schedule_config=schedule_config,
)
except AutomationSchemaError as error:
raise serializers.ValidationError({"detail": str(error)}) from error
attrs.update(normalized)
applies_to_all = attrs.get(
"applies_to_all_boards",
getattr(instance, "applies_to_all_boards", True),
)
boards = attrs.get("boards")
if not applies_to_all and boards is not None and not boards:
raise serializers.ValidationError(
{"boards": "Выберите хотя бы одну доску или включите все доски."}
)
if applies_to_all:
attrs["boards"] = []
return attrs