105 lines
3.5 KiB
Python

"""Approval workflow serializers for procurement requests."""
from django.contrib.auth import get_user_model
from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers
from procurement.constants import get_default_approval_step_name
from procurement.models import Approval, ApprovalRoute
from ...employees.serializers import DepartmentBriefSerializer, EmployeeBriefSerializer
User = get_user_model()
class ProcurementRequestCreateOptionsSerializer(serializers.Serializer):
"""Опции формы создания заявки на закупку."""
processing_departments = DepartmentBriefSerializer(many=True)
default_processing_department = serializers.IntegerField(allow_null=True)
subscription_processing_departments = DepartmentBriefSerializer(many=True)
subscription_default_processing_department = serializers.IntegerField(
allow_null=True
)
class ProcurementManualApprovalStepSerializer(serializers.Serializer):
"""Ручной этап согласования при отправке заявки."""
priority = serializers.IntegerField(min_value=1)
approver = serializers.PrimaryKeyRelatedField(
queryset=User.objects.visible_in_ui().filter(is_active=True),
)
step_name = serializers.CharField(
required=False,
allow_blank=True,
max_length=150,
)
def validate_priority(self, value):
if not ApprovalRoute.objects.filter(priority=value).exists():
raise serializers.ValidationError("Выберите настроенный этап согласования.")
return value
class ProcurementManualApprovalStepsSerializer(serializers.Serializer):
"""Список ручных этапов согласования."""
approval_steps = ProcurementManualApprovalStepSerializer(
many=True,
required=False,
allow_empty=True,
)
def validate_approval_steps(self, value):
priorities = [item["priority"] for item in value]
duplicate_priorities = {
priority for priority in priorities if priorities.count(priority) > 1
}
if duplicate_priorities:
raise serializers.ValidationError(
"Каждый этап согласования можно выбрать только один раз."
)
return value
class ApprovalSerializer(serializers.ModelSerializer):
"""Сериализатор для согласований."""
approver = EmployeeBriefSerializer(read_only=True)
approver_name = serializers.CharField(
source="approver.get_full_name", read_only=True
)
status_display = serializers.CharField(source="get_status_display", read_only=True)
step_label = serializers.SerializerMethodField()
@extend_schema_field(serializers.CharField())
def get_step_label(self, obj):
return obj.step_name or get_default_approval_step_name(obj.priority)
class Meta:
model = Approval
fields = [
"id",
"request",
"approver",
"approver_name",
"priority",
"step_name",
"step_label",
"status",
"status_display",
"comment",
"created_at",
"updated_at",
]
read_only_fields = [
"id",
"created_at",
"updated_at",
"approver_name",
"step_name",
"step_label",
"status_display",
]