Corp/backend/api/v1/commerce/serializers.py
2026-08-17 18:38:22 +03:00

222 lines
6.2 KiB
Python
Raw 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.

from rest_framework import serializers
from commerce.models import (
Cost,
Product,
ProductBinding,
Sale,
SaleLine,
SourceSystem,
StockSnapshot,
)
class SourceSystemSerializer(serializers.ModelSerializer):
class Meta:
model = SourceSystem
fields = [
"id",
"code",
"name",
"is_active",
"metadata",
"created_at",
"updated_at",
]
read_only_fields = ["id", "created_at", "updated_at"]
class ProductBindingSerializer(serializers.ModelSerializer):
source_code = serializers.CharField(source="source.code", read_only=True)
class Meta:
model = ProductBinding
fields = [
"id",
"product",
"source",
"source_code",
"external_id",
"external_sku",
"is_primary",
"created_at",
"updated_at",
]
read_only_fields = ["id", "created_at", "updated_at"]
class ProductSerializer(serializers.ModelSerializer):
bindings = ProductBindingSerializer(many=True, read_only=True)
variants_count = serializers.IntegerField(read_only=True)
class Meta:
model = Product
fields = [
"id",
"parent",
"kind",
"sku",
"name",
"barcode",
"description",
"is_active",
"variants_count",
"bindings",
"created_at",
"updated_at",
]
read_only_fields = ["id", "created_at", "updated_at"]
class SaleLineSerializer(serializers.ModelSerializer):
net_amount = serializers.DecimalField(
max_digits=18, decimal_places=2, read_only=True
)
class Meta:
model = SaleLine
fields = [
"id",
"sale",
"product",
"external_id",
"external_product_id",
"external_sku",
"name",
"quantity",
"gross_amount",
"discount_amount",
"net_amount",
"cost_amount",
"metadata",
]
def validate(self, attrs):
gross = attrs.get("gross_amount", getattr(self.instance, "gross_amount", 0))
discount = attrs.get(
"discount_amount", getattr(self.instance, "discount_amount", 0)
)
if discount > gross:
raise serializers.ValidationError(
{"discount_amount": "Скидка не может превышать сумму позиции."}
)
return attrs
class SaleSerializer(serializers.ModelSerializer):
source_code = serializers.CharField(source="source.code", read_only=True)
lines = SaleLineSerializer(many=True, read_only=True)
class Meta:
model = Sale
fields = [
"id",
"source",
"source_code",
"source_record",
"external_id",
"number",
"event_type",
"channel",
"status",
"counts_as_sale",
"currency",
"occurred_at",
"source_updated_at",
"lines",
"created_at",
"updated_at",
]
class CostSerializer(serializers.ModelSerializer):
source_code = serializers.CharField(source="source.code", read_only=True)
class Meta:
model = Cost
fields = [
"id",
"source",
"source_code",
"product",
"sale_line",
"external_id",
"channel",
"cost_type",
"amount",
"currency",
"occurred_at",
"metadata",
"created_at",
]
validators = []
def validate(self, attrs):
product = attrs.get("product", getattr(self.instance, "product", None))
sale_line = attrs.get("sale_line", getattr(self.instance, "sale_line", None))
if product is None and sale_line is None:
raise serializers.ValidationError(
"Нужно указать товар или позицию продажи."
)
external_id = attrs.get(
"external_id", getattr(self.instance, "external_id", "")
)
if external_id:
source = attrs.get("source", getattr(self.instance, "source", None))
cost_type = attrs.get(
"cost_type", getattr(self.instance, "cost_type", None)
)
duplicate = Cost.objects.filter(
source=source,
external_id=external_id,
cost_type=cost_type,
)
if self.instance:
duplicate = duplicate.exclude(pk=self.instance.pk)
if duplicate.exists():
raise serializers.ValidationError(
{"external_id": "Расход с таким внешним ID уже существует."}
)
return attrs
class StockSnapshotSerializer(serializers.ModelSerializer):
source_code = serializers.CharField(source="source.code", read_only=True)
available = serializers.DecimalField(
max_digits=18, decimal_places=4, read_only=True
)
class Meta:
model = StockSnapshot
fields = [
"id",
"product",
"source",
"source_code",
"warehouse_external_id",
"warehouse_name",
"quantity",
"reserved",
"available",
"in_transit",
"captured_at",
"metadata",
"created_at",
]
class ProductMetricsQuerySerializer(serializers.Serializer):
date_from = serializers.DateTimeField(required=False)
date_to = serializers.DateTimeField(required=False)
def validate(self, attrs):
if (
attrs.get("date_from")
and attrs.get("date_to")
and attrs["date_from"] > attrs["date_to"]
):
raise serializers.ValidationError(
{"date_to": "Дата окончания должна быть не раньше даты начала."}
)
return attrs