2026-09-07 19:43:48 +03:00

181 lines
6.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Equipment serializers."""
from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers
from procurement.models import Equipment
from procurement.services import InventoryNumberGenerator
from ..equipment_policy import (
EquipmentCreationPolicy,
EquipmentPolicyValidationError,
validate_responsible_department,
)
class EquipmentListSerializer(serializers.ModelSerializer):
"""Сериализатор для списка оборудования."""
category_name = serializers.CharField(source="category.name", read_only=True)
category_icon = serializers.CharField(
source="category.icon", read_only=True, default="bi-box-seam"
)
department_name = serializers.CharField(source="department.name", read_only=True)
responsible_name = serializers.CharField(
source="responsible_person.get_full_name", read_only=True
)
status_display = serializers.CharField(source="get_status_display", read_only=True)
is_under_warranty = serializers.BooleanField(read_only=True)
comments_count = serializers.IntegerField(read_only=True, default=0)
class Meta:
model = Equipment
fields = [
"id",
"name",
"inventory_number",
"serial_number",
"category",
"category_name",
"category_icon",
"status",
"status_display",
"department",
"department_name",
"responsible_person",
"responsible_name",
"location",
"purchase_date",
"purchase_cost",
"notes",
"is_under_warranty",
"comments_count",
"created_at",
"updated_at",
]
read_only_fields = [
"id",
"inventory_number",
"category_name",
"category_icon",
"department_name",
"responsible_name",
"status_display",
"is_under_warranty",
"comments_count",
"created_at",
"updated_at",
]
def create(self, validated_data):
"""Автоматическая генерация инвентарного номера при создании."""
validated_data["inventory_number"] = InventoryNumberGenerator.generate()
return super().create(validated_data)
def validate(self, attrs):
"""Validate department access and responsible-person consistency."""
request = self.context.get("request")
user = request.user if request else None
try:
if self.instance is None:
responsible = attrs.get("responsible_person")
if responsible is not None and not responsible.is_active:
raise EquipmentPolicyValidationError(
{
"responsible_person": (
"Ответственным может быть только активный сотрудник."
)
}
)
return EquipmentCreationPolicy.resolve(user).validate_create(attrs)
department = attrs.get("department", self.instance.department)
responsible = attrs.get(
"responsible_person",
self.instance.responsible_person,
)
responsible_changed = (
"responsible_person" in attrs
and getattr(responsible, "id", None)
!= self.instance.responsible_person_id
)
department_changed = (
"department" in attrs and department.id != self.instance.department_id
)
if (
responsible_changed
and responsible is not None
and not responsible.is_active
):
raise EquipmentPolicyValidationError(
{
"responsible_person": (
"Ответственным может быть только активный сотрудник."
)
}
)
if (
responsible is not None
and responsible.is_active
and (responsible_changed or department_changed)
):
validate_responsible_department(
department=department,
responsible=responsible,
)
return attrs
except EquipmentPolicyValidationError as exc:
raise serializers.ValidationError(exc.errors) from exc
class EquipmentDetailSerializer(serializers.ModelSerializer):
"""Сериализатор для детальной информации об оборудовании."""
category_name = serializers.CharField(source="category.name", read_only=True)
department_name = serializers.CharField(source="department.name", read_only=True)
responsible_name = serializers.CharField(
source="responsible_person.get_full_name", read_only=True
)
status_display = serializers.CharField(source="get_status_display", read_only=True)
is_under_warranty = serializers.BooleanField(read_only=True)
maintenance_count = serializers.SerializerMethodField()
class Meta:
model = Equipment
fields = [
"id",
"name",
"inventory_number",
"serial_number",
"category",
"category_name",
"status",
"status_display",
"department",
"department_name",
"responsible_person",
"responsible_name",
"location",
"purchase_date",
"warranty_until",
"is_under_warranty",
"purchase_cost",
"notes",
"maintenance_count",
"created_at",
"updated_at",
]
read_only_fields = [
"id",
"created_at",
"updated_at",
"is_under_warranty",
"maintenance_count",
]
@extend_schema_field(serializers.IntegerField())
def get_maintenance_count(self, obj):
"""Количество записей обслуживания."""
return obj.maintenance_history.count()