"""purchase 序列化器(async 兼容)。""" from rest_framework import serializers from apps.core.serializers import AsyncModelSerializer from .models import PurchaseOrder, PurchaseOrderLine, PurchaseBill, PurchaseBillLine class PurchaseOrderLineSerializer(AsyncModelSerializer): product_code = serializers.CharField(source="product.code", read_only=True) product_name = serializers.CharField(source="product.name", read_only=True) class Meta: model = PurchaseOrderLine fields = ["id", "product", "product_code", "product_name", "quantity", "unit_price", "amount", "received_qty"] read_only_fields = ["id", "amount", "received_qty"] class PurchaseOrderSerializer(AsyncModelSerializer): supplier_code = serializers.CharField(source="supplier.code", read_only=True) warehouse_code = serializers.CharField(source="warehouse.code", read_only=True) lines = PurchaseOrderLineSerializer(many=True, required=False) class Meta: model = PurchaseOrder fields = [ "id", "bill_no", "supplier", "supplier_code", "warehouse", "warehouse_code", "bill_date", "expected_date", "total_amount", "state", "remark", "lines", ] read_only_fields = ["id", "bill_no", "total_amount", "state"] def create(self, validated_data): lines = validated_data.pop("lines", []) tenant = self.context["request"]._request.tenant if hasattr(self.context.get("request", None), "_request") else None # 多租户注入由 acreate 处理(参考 catalog) from django.db import transaction from datetime import date with transaction.atomic(): order = PurchaseOrder.objects.create(**validated_data) total = Decimal = __import__("decimal").Decimal tot = total("0") for ln in lines: qty = total(str(ln["quantity"])) price = total(str(ln["unit_price"])) PurchaseOrderLine.objects.create( tenant=order.tenant, order=order, product=ln["product"], quantity=qty, unit_price=price, amount=qty * price, ) tot += qty * price order.total_amount = tot order.save(update_fields=["total_amount"]) return order class PurchaseBillLineSerializer(AsyncModelSerializer): product_code = serializers.CharField(source="product.code", read_only=True) product_name = serializers.CharField(source="product.name", read_only=True) unit_name = serializers.SerializerMethodField() is_batch_managed = serializers.BooleanField( source="product.is_batch_managed", read_only=True ) class Meta: model = PurchaseBillLine fields = ["id", "product", "product_code", "product_name", "quantity", "source_unit", "source_quantity", "unit_name", "unit_price", "amount", "tax_rate", "tax_amount", "batch_no", "production_date", "expiry_date", "is_batch_managed"] read_only_fields = ["id", "amount"] def get_unit_name(self, obj): unit = obj.source_unit or getattr(obj.product, "base_unit", None) return unit.name if unit else "" class PurchaseBillSerializer(AsyncModelSerializer): supplier_code = serializers.CharField(source="supplier.code", read_only=True) supplier_name = serializers.CharField(source="supplier.name", read_only=True) warehouse_code = serializers.CharField(source="warehouse.code", read_only=True) lines = PurchaseBillLineSerializer(many=True, required=False) class Meta: model = PurchaseBill fields = [ "id", "bill_no", "supplier", "supplier_code", "supplier_name", "warehouse", "warehouse_code", "order", "bill_date", "total_amount", "state", "remark", "lines", ] read_only_fields = ["id", "bill_no", "total_amount", "state"]