98 lines
4.0 KiB
Python
98 lines
4.0 KiB
Python
"""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"]
|