1
0
forked from erp-dev/erp

feat: added new api for query batch_advance_records

This commit is contained in:
2026-01-07 15:06:55 +08:00
parent 4566c2a2c8
commit 5b07332015
5 changed files with 400 additions and 0 deletions

View File

@@ -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)

View File

@@ -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'),

View File

@@ -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',
]

View File

@@ -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(),
})