forked from erp-dev/erp
feat: added new api for query batch_advance_records
This commit is contained in:
138
api_v2/tests.py
138
api_v2/tests.py
@@ -1516,3 +1516,141 @@ class MyVisiblePagesAPITest(TestCase):
|
||||
self.client.logout()
|
||||
response = self.client.get('/api/v2/me/visible-pages/')
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
|
||||
class PrintingOrderBatchAdvanceRecordsAPITest(TestCase):
|
||||
"""测试印染订单批量推进记录查询 API"""
|
||||
|
||||
def setUp(self):
|
||||
self.client = APIClient()
|
||||
self.merchant = basic_models.Merchant.objects.create(
|
||||
name='测试商户',
|
||||
type=basic_models.MerchantTypeEnum.FACTORY,
|
||||
)
|
||||
self.user = get_user_model().objects.create_user(username='testuser', password='pass12345')
|
||||
self.client.force_authenticate(user=self.user)
|
||||
|
||||
# 创建客户
|
||||
self.customer = basic_models.Customer.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='测试客户'
|
||||
)
|
||||
|
||||
# 创建产品类别和产品
|
||||
self.category = basic_models.ProductCategory.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='测试类别'
|
||||
)
|
||||
self.product = basic_models.Product.objects.create(
|
||||
merchant=self.merchant,
|
||||
name='测试产品',
|
||||
category=self.category,
|
||||
unit=basic_models.ProductUnitEnum.METER
|
||||
)
|
||||
|
||||
# 创建印染订单
|
||||
self.printing_order = printing_models.PrintingOrder.objects.create(
|
||||
customer=self.customer,
|
||||
fabric='测试面料',
|
||||
width='150cm'
|
||||
)
|
||||
|
||||
# 创建印染明细
|
||||
self.job1 = printing_models.PrintingJob.objects.create(
|
||||
printing_order=self.printing_order,
|
||||
product=self.product,
|
||||
quantity=100,
|
||||
unit='米'
|
||||
)
|
||||
self.job2 = printing_models.PrintingJob.objects.create(
|
||||
printing_order=self.printing_order,
|
||||
product=self.product,
|
||||
quantity=200,
|
||||
unit='米'
|
||||
)
|
||||
|
||||
# 创建流程状态
|
||||
self.state = stateflow_models.State.objects.create(
|
||||
name='染色',
|
||||
description='染色工序'
|
||||
)
|
||||
|
||||
# 创建批量推进记录
|
||||
self.record = printing_models.PrintingJobBatchAdvanceRecord.objects.create(
|
||||
printing_order=self.printing_order,
|
||||
state=self.state,
|
||||
created_by=self.user,
|
||||
parameters={'temperature': '25.5', 'operator': '张三'}
|
||||
)
|
||||
self.record.printing_jobs.add(self.job1, self.job2)
|
||||
|
||||
def test_get_batch_advance_records_success(self):
|
||||
"""测试成功获取批量推进记录"""
|
||||
response = self.client.get(f'/api/v2/printing-orders/{self.printing_order.id}/batch-advance-records/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
data = response.data
|
||||
self.assertEqual(data['printing_order_id'], self.printing_order.id)
|
||||
self.assertEqual(data['total_count'], 1)
|
||||
self.assertEqual(len(data['records']), 1)
|
||||
|
||||
record = data['records'][0]
|
||||
self.assertEqual(record['id'], self.record.id)
|
||||
self.assertEqual(record['state_id'], self.state.id)
|
||||
self.assertEqual(record['state_name'], '染色')
|
||||
self.assertEqual(record['created_by'], self.user.id)
|
||||
self.assertEqual(record['created_by_username'], 'testuser')
|
||||
self.assertEqual(record['parameters'], {'temperature': '25.5', 'operator': '张三'})
|
||||
self.assertEqual(record['printing_job_count'], 2)
|
||||
self.assertIn(self.job1.id, record['printing_job_ids'])
|
||||
self.assertIn(self.job2.id, record['printing_job_ids'])
|
||||
|
||||
def test_get_batch_advance_records_empty(self):
|
||||
"""测试没有批量推进记录时返回空列表"""
|
||||
# 创建另一个没有记录的订单
|
||||
another_order = printing_models.PrintingOrder.objects.create(
|
||||
customer=self.customer,
|
||||
fabric='测试面料2',
|
||||
width='160cm'
|
||||
)
|
||||
|
||||
response = self.client.get(f'/api/v2/printing-orders/{another_order.id}/batch-advance-records/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
data = response.data
|
||||
self.assertEqual(data['printing_order_id'], another_order.id)
|
||||
self.assertEqual(data['total_count'], 0)
|
||||
self.assertEqual(data['records'], [])
|
||||
|
||||
def test_get_batch_advance_records_order_not_found(self):
|
||||
"""测试订单不存在时返回 404"""
|
||||
response = self.client.get('/api/v2/printing-orders/99999/batch-advance-records/')
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertIn('error', response.data)
|
||||
|
||||
def test_get_batch_advance_records_multiple_records(self):
|
||||
"""测试多条批量推进记录按时间倒序返回"""
|
||||
# 创建第二条记录
|
||||
state2 = stateflow_models.State.objects.create(name='整理', description='整理工序')
|
||||
record2 = printing_models.PrintingJobBatchAdvanceRecord.objects.create(
|
||||
printing_order=self.printing_order,
|
||||
state=state2,
|
||||
created_by=self.user,
|
||||
parameters={'notes': '完成'}
|
||||
)
|
||||
record2.printing_jobs.add(self.job1)
|
||||
|
||||
response = self.client.get(f'/api/v2/printing-orders/{self.printing_order.id}/batch-advance-records/')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
data = response.data
|
||||
self.assertEqual(data['total_count'], 2)
|
||||
# 最新的记录应该在前面
|
||||
self.assertEqual(data['records'][0]['id'], record2.id)
|
||||
self.assertEqual(data['records'][1]['id'], self.record.id)
|
||||
|
||||
def test_get_batch_advance_records_unauthenticated(self):
|
||||
"""测试未登录时返回 401"""
|
||||
self.client.logout()
|
||||
response = self.client.get(f'/api/v2/printing-orders/{self.printing_order.id}/batch-advance-records/')
|
||||
self.assertEqual(response.status_code, 401)
|
||||
|
||||
@@ -11,6 +11,7 @@ from api_v2.views import (
|
||||
PlateOrderByProcessView,
|
||||
PlateOrderByStateStatusView,
|
||||
PlateOrderBatchUpdateView,
|
||||
PrintingOrderBatchAdvanceRecordsView,
|
||||
BusinessObjectCloneView,
|
||||
)
|
||||
from api_v2.views.basic_info import CustomerEmployeeBindingView, MyVisiblePagesView
|
||||
@@ -24,6 +25,7 @@ urlpatterns = [
|
||||
path('printing-jobs/by-customer/', PrintingJobByCustomerView.as_view(), name='api_v2_printing_job_by_customer'),
|
||||
path('printing-jobs/batch-advance/preview/', PrintingJobBatchAdvancePreviewView.as_view(), name='api_v2_printing_job_batch_advance_preview'),
|
||||
path('printing-jobs/batch-advance/', PrintingJobBatchAdvanceSubmitView.as_view(), name='api_v2_printing_job_batch_advance_submit'),
|
||||
path('printing-orders/<int:printing_order_id>/batch-advance-records/', PrintingOrderBatchAdvanceRecordsView.as_view(), name='api_v2_printing_order_batch_advance_records'),
|
||||
path('plate-orders/by-process-node/', PlateOrderByProcessNodeView.as_view(), name='api_v2_plate_order_by_process_node'),
|
||||
path('plate-orders/by-process/', PlateOrderByProcessView.as_view(), name='api_v2_plate_order_by_process'),
|
||||
path('plate-orders/by-state-status/', PlateOrderByStateStatusView.as_view(), name='api_v2_plate_order_by_state_status'),
|
||||
|
||||
@@ -13,6 +13,7 @@ from .printing import (
|
||||
PlateOrderByProcessView,
|
||||
PlateOrderByStateStatusView,
|
||||
PlateOrderBatchUpdateView,
|
||||
PrintingOrderBatchAdvanceRecordsView,
|
||||
)
|
||||
from .stateflow import BusinessObjectCloneView
|
||||
|
||||
@@ -28,6 +29,7 @@ __all__ = [
|
||||
'PlateOrderByProcessView',
|
||||
'PlateOrderByStateStatusView',
|
||||
'PlateOrderBatchUpdateView',
|
||||
'PrintingOrderBatchAdvanceRecordsView',
|
||||
'BusinessObjectCloneView',
|
||||
]
|
||||
|
||||
|
||||
@@ -1345,3 +1345,116 @@ class PlateOrderBatchUpdateView(APIView):
|
||||
"plate_order_ids": found_ids,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class BatchAdvanceRecordSerializer(serializers.ModelSerializer):
|
||||
"""批量推进记录序列化器"""
|
||||
|
||||
state_id = serializers.IntegerField(source='state.id', read_only=True)
|
||||
state_name = serializers.CharField(source='state.name', read_only=True)
|
||||
created_by_username = serializers.CharField(source='created_by.username', read_only=True, allow_null=True)
|
||||
created_by_name = serializers.SerializerMethodField()
|
||||
printing_job_ids = serializers.SerializerMethodField()
|
||||
printing_job_count = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = printing_models.PrintingJobBatchAdvanceRecord
|
||||
fields = [
|
||||
'id',
|
||||
'printing_order',
|
||||
'state',
|
||||
'state_id',
|
||||
'state_name',
|
||||
'created_by',
|
||||
'created_by_username',
|
||||
'created_by_name',
|
||||
'parameters',
|
||||
'printing_job_ids',
|
||||
'printing_job_count',
|
||||
'created_at',
|
||||
]
|
||||
read_only_fields = fields
|
||||
|
||||
def get_created_by_name(self, obj):
|
||||
"""获取操作人员工姓名"""
|
||||
user = getattr(obj, 'created_by', None)
|
||||
if not user:
|
||||
return None
|
||||
emp = getattr(user, 'employee', None)
|
||||
return getattr(emp, 'name', None)
|
||||
|
||||
def get_printing_job_ids(self, obj):
|
||||
"""获取涉及的印染明细 ID 列表"""
|
||||
# 使用预取的数据避免 N+1
|
||||
if hasattr(obj, '_prefetched_objects_cache') and 'printing_jobs' in obj._prefetched_objects_cache:
|
||||
return [job.id for job in obj.printing_jobs.all()]
|
||||
return list(obj.printing_jobs.values_list('id', flat=True))
|
||||
|
||||
def get_printing_job_count(self, obj):
|
||||
"""获取涉及的印染明细数量"""
|
||||
if hasattr(obj, '_prefetched_objects_cache') and 'printing_jobs' in obj._prefetched_objects_cache:
|
||||
return len(obj.printing_jobs.all())
|
||||
return obj.printing_jobs.count()
|
||||
|
||||
|
||||
class PrintingOrderBatchAdvanceRecordsView(APIView):
|
||||
"""
|
||||
获取印染订单的批量推进记录
|
||||
|
||||
根据 printing_order_id 查询该订单下所有的批量推进审计记录。
|
||||
|
||||
GET /api/v2/printing-orders/{printing_order_id}/batch-advance-records/
|
||||
|
||||
响应示例:
|
||||
{
|
||||
"printing_order_id": 55,
|
||||
"records": [
|
||||
{
|
||||
"id": 9,
|
||||
"printing_order": 55,
|
||||
"state": 7,
|
||||
"state_id": 7,
|
||||
"state_name": "染色",
|
||||
"created_by": 1001,
|
||||
"created_by_username": "factory_user",
|
||||
"created_by_name": "张三",
|
||||
"parameters": {"temperature": "25.5"},
|
||||
"printing_job_ids": [101, 102, 103],
|
||||
"printing_job_count": 3,
|
||||
"created_at": "2025-12-14T10:00:00+08:00"
|
||||
}
|
||||
],
|
||||
"total_count": 1
|
||||
}
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.IsAuthenticated]
|
||||
|
||||
def get(self, request, printing_order_id):
|
||||
# 验证订单是否存在
|
||||
try:
|
||||
printing_order = printing_models.PrintingOrder.objects.get(id=printing_order_id)
|
||||
except printing_models.PrintingOrder.DoesNotExist:
|
||||
return Response(
|
||||
{'error': f'未找到 ID 为 {printing_order_id} 的印染订单'},
|
||||
status=status.HTTP_404_NOT_FOUND
|
||||
)
|
||||
|
||||
# 查询批量推进记录,按创建时间倒序
|
||||
records = printing_models.PrintingJobBatchAdvanceRecord.objects.filter(
|
||||
printing_order_id=printing_order_id
|
||||
).select_related(
|
||||
'state',
|
||||
'created_by',
|
||||
'created_by__employee',
|
||||
).prefetch_related(
|
||||
'printing_jobs',
|
||||
).order_by('-created_at')
|
||||
|
||||
serializer = BatchAdvanceRecordSerializer(records, many=True)
|
||||
|
||||
return Response({
|
||||
'printing_order_id': printing_order_id,
|
||||
'records': serializer.data,
|
||||
'total_count': records.count(),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user