baseline: 批次A-D 成果 + membership 半成品(测试红)
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
"""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"]
|
||||
Reference in New Issue
Block a user