forked from erp-dev/erp
feat: added sales_items and external_products into shipments list api
This commit is contained in:
@@ -3,7 +3,7 @@ Shipment API 序列化器
|
||||
"""
|
||||
from rest_framework import serializers
|
||||
|
||||
from shipment.models import Shipment
|
||||
from shipment.models import ExternalFinishedProduct, SalesItem, Shipment
|
||||
|
||||
|
||||
class ShipmentSerializer(serializers.ModelSerializer):
|
||||
@@ -20,6 +20,8 @@ class ShipmentSerializer(serializers.ModelSerializer):
|
||||
external_finished_products_count = serializers.SerializerMethodField()
|
||||
merchant_id = serializers.IntegerField(source='merchant.id', read_only=True)
|
||||
merchant_name = serializers.CharField(source='merchant.name', read_only=True)
|
||||
sales_items = serializers.SerializerMethodField()
|
||||
external_finished_products = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Shipment
|
||||
@@ -31,6 +33,8 @@ class ShipmentSerializer(serializers.ModelSerializer):
|
||||
'cancelled_at', 'cancelled_by_id', 'cancelled_by_name',
|
||||
'items_count', 'created_by_id', 'created_by_name',
|
||||
'external_finished_products_count',
|
||||
'sales_items',
|
||||
'external_finished_products',
|
||||
'created_at', 'updated_at'
|
||||
]
|
||||
read_only_fields = ['id', 'created_at', 'updated_at']
|
||||
@@ -57,6 +61,51 @@ class ShipmentSerializer(serializers.ModelSerializer):
|
||||
def get_external_finished_products_count(self, obj):
|
||||
return obj.external_finished_products.count()
|
||||
|
||||
def get_sales_items(self, obj):
|
||||
"""
|
||||
出货单关联的销售品明细(无则返回空数组)。
|
||||
"""
|
||||
# 优先使用 prefetch 的 related manager;兜底为 none()
|
||||
rel = getattr(obj, 'items', None)
|
||||
items = list(rel.all()) if rel is not None else []
|
||||
return SalesItemSerializer(items, many=True).data
|
||||
|
||||
def get_external_finished_products(self, obj):
|
||||
"""
|
||||
出货单关联的外部成品表明细(无则返回空数组)。
|
||||
"""
|
||||
rel = getattr(obj, 'external_finished_products', None)
|
||||
products = list(rel.all()) if rel is not None else []
|
||||
return ExternalFinishedProductSerializer(products, many=True).data
|
||||
|
||||
|
||||
class ExternalFinishedProductSerializer(serializers.ModelSerializer):
|
||||
"""
|
||||
外部成品表序列化器(只读)
|
||||
"""
|
||||
created_by_id = serializers.IntegerField(source='created_by.id', read_only=True, allow_null=True)
|
||||
created_by_name = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = ExternalFinishedProduct
|
||||
fields = [
|
||||
'id',
|
||||
'style_name',
|
||||
'num_of_rolls',
|
||||
'created_at',
|
||||
'created_by_id',
|
||||
'created_by_name',
|
||||
]
|
||||
read_only_fields = fields
|
||||
|
||||
def get_created_by_name(self, obj):
|
||||
if obj.created_by:
|
||||
employee = getattr(obj.created_by, 'employee', None)
|
||||
if employee:
|
||||
return employee.name
|
||||
return obj.created_by.username
|
||||
return None
|
||||
|
||||
|
||||
class ShipmentCreateNormalSerializer(serializers.Serializer):
|
||||
"""
|
||||
|
||||
@@ -638,10 +638,22 @@ class ShipmentQueryAPITestCase(TestCase):
|
||||
self.assertIn(self.shipment1.id, ids)
|
||||
self.assertNotIn(self.shipment2.id, ids)
|
||||
|
||||
# 关键:列表序列化器必须稳定输出明细数组字段(即使为空)
|
||||
item = next(it for it in data['results'] if it['id'] == self.shipment1.id)
|
||||
self.assertIn('sales_items', item)
|
||||
self.assertIsInstance(item['sales_items'], list)
|
||||
self.assertIn('external_finished_products', item)
|
||||
self.assertIsInstance(item['external_finished_products'], list)
|
||||
|
||||
def test_retrieve_shipment_success(self):
|
||||
resp = self.client.get(f'/api/v1/shipment/shipments/{self.shipment1.id}/')
|
||||
self.assertEqual(resp.status_code, status.HTTP_200_OK)
|
||||
self.assertEqual(resp.json()['id'], self.shipment1.id)
|
||||
result = resp.json()
|
||||
self.assertEqual(result['id'], self.shipment1.id)
|
||||
self.assertIn('sales_items', result)
|
||||
self.assertIsInstance(result['sales_items'], list)
|
||||
self.assertIn('external_finished_products', result)
|
||||
self.assertIsInstance(result['external_finished_products'], list)
|
||||
|
||||
def test_retrieve_other_merchant_shipment_404(self):
|
||||
resp = self.client.get(f'/api/v1/shipment/shipments/{self.shipment2.id}/')
|
||||
|
||||
Reference in New Issue
Block a user