231 lines
6.8 KiB
Python

"""Procurement item and attachment serializers."""
from drf_spectacular.utils import extend_schema_field
from rest_framework import serializers
from communications import comments_helpers
from procurement.models import ProcurementItem, ProcurementItemAttachment
from .common import _validate_expected_delivery_dates
class ProcurementItemAttachmentSerializer(serializers.ModelSerializer):
uploaded_by_name = serializers.CharField(
source="uploaded_by.get_full_name",
read_only=True,
)
download_url = serializers.SerializerMethodField()
thumbnail_url = serializers.SerializerMethodField()
class Meta:
model = ProcurementItemAttachment
fields = [
"id",
"file_name",
"file_size",
"mime_type",
"uploaded_by",
"uploaded_by_name",
"created_at",
"download_url",
"thumbnail_url",
]
read_only_fields = fields
def get_download_url(self, obj) -> str:
return f"/api/v1/procurement/items/{obj.item_id}/attachments/{obj.id}/"
def get_thumbnail_url(self, obj) -> str | None:
from procurement.media import procurement_attachment_media_kind
if not procurement_attachment_media_kind(obj):
return None
return (
f"/api/v1/procurement/items/{obj.item_id}/attachments/{obj.id}/thumbnail/"
)
class ProcurementItemSerializer(serializers.ModelSerializer):
"""Сериализатор для позиций заявки."""
estimated_unit_price = serializers.DecimalField(
max_digits=12,
decimal_places=2,
required=False,
allow_null=True,
)
ordered_quantity = serializers.IntegerField(
required=False,
allow_null=True,
min_value=0,
)
received_quantity = serializers.IntegerField(
required=False,
allow_null=True,
min_value=0,
)
expected_delivery_dates = serializers.ListField(
child=serializers.CharField(allow_blank=False, trim_whitespace=True),
required=False,
allow_empty=True,
)
initial_comment = serializers.CharField(
write_only=True,
required=False,
allow_blank=True,
)
total_price = serializers.DecimalField(
max_digits=12, decimal_places=2, read_only=True
)
execution_status_display = serializers.SerializerMethodField()
comments_count = serializers.SerializerMethodField()
attachments = ProcurementItemAttachmentSerializer(many=True, read_only=True)
attachments_count = serializers.IntegerField(
source="attachments.count",
read_only=True,
)
@extend_schema_field(serializers.IntegerField())
def get_comments_count(self, obj):
annotated_count = getattr(obj, "comments_count", None)
if annotated_count is not None:
return annotated_count
from communications.comments_helpers import get_comment_count
return get_comment_count(obj)
@extend_schema_field(serializers.CharField())
def get_execution_status_display(self, obj):
return obj.execution_status_display
class Meta:
model = ProcurementItem
fields = [
"id",
"request",
"name",
"description",
"quantity",
"unit",
"estimated_unit_price",
"total_price",
"ordered_quantity",
"received_quantity",
"supplier_info",
"links",
"expected_delivery_dates",
"actual_unit_price",
"execution_status",
"execution_status_display",
"defective_at",
"executor_comment",
"initial_comment",
"comments_count",
"attachments",
"attachments_count",
"equipment",
"created_at",
]
read_only_fields = [
"id",
"created_at",
"total_price",
"execution_status_display",
"defective_at",
"comments_count",
"attachments",
"attachments_count",
]
def validate_expected_delivery_dates(self, value):
return _validate_expected_delivery_dates(value)
def create(self, validated_data):
initial_comment = validated_data.pop("initial_comment", "").strip()
item = super().create(validated_data)
request = self.context.get("request")
author = getattr(request, "user", None)
if initial_comment and author and author.is_authenticated:
comments_helpers.create_comment(
obj=item,
author=author,
content=initial_comment,
)
return item
class ProcurementItemCreateSerializer(serializers.ModelSerializer):
"""Сериализатор для создания позиций (без request)."""
estimated_unit_price = serializers.DecimalField(
max_digits=12,
decimal_places=2,
required=False,
allow_null=True,
)
ordered_quantity = serializers.IntegerField(
required=False,
allow_null=True,
min_value=0,
)
received_quantity = serializers.IntegerField(
required=False,
allow_null=True,
min_value=0,
)
expected_delivery_dates = serializers.ListField(
child=serializers.CharField(allow_blank=False, trim_whitespace=True),
required=False,
allow_empty=True,
)
initial_comment = serializers.CharField(
write_only=True,
required=False,
allow_blank=True,
)
class Meta:
model = ProcurementItem
fields = [
"id",
"name",
"description",
"quantity",
"unit",
"estimated_unit_price",
"ordered_quantity",
"received_quantity",
"supplier_info",
"links",
"expected_delivery_dates",
"actual_unit_price",
"execution_status",
"executor_comment",
"initial_comment",
]
read_only_fields = ["id"]
def validate_expected_delivery_dates(self, value):
return _validate_expected_delivery_dates(value)
class ProcurementItemEditSerializer(ProcurementItemCreateSerializer):
"""Сериализатор для редактирования позиций внутри заявки."""
id = serializers.IntegerField(required=False)
class Meta:
model = ProcurementItem
fields = [
"id",
"name",
"description",
"quantity",
"unit",
"estimated_unit_price",
"supplier_info",
"links",
"initial_comment",
]