forked from erp-dev/erp
feat: batch add parameters
This commit is contained in:
@@ -1348,7 +1348,7 @@ class PlateOrderBatchUpdateView(APIView):
|
||||
|
||||
|
||||
class BatchAdvanceRecordSerializer(serializers.ModelSerializer):
|
||||
"""批量推进记录序列化器"""
|
||||
"""批量操作记录序列化器"""
|
||||
|
||||
state_id = serializers.IntegerField(source='state.id', read_only=True)
|
||||
state_name = serializers.CharField(source='state.name', read_only=True)
|
||||
@@ -1369,6 +1369,7 @@ class BatchAdvanceRecordSerializer(serializers.ModelSerializer):
|
||||
'created_by_username',
|
||||
'created_by_name',
|
||||
'parameters',
|
||||
'only_parameters',
|
||||
'printing_job_ids',
|
||||
'printing_job_count',
|
||||
'created_at',
|
||||
@@ -1458,3 +1459,200 @@ class PrintingOrderBatchAdvanceRecordsView(APIView):
|
||||
'records': serializer.data,
|
||||
'total_count': records.count(),
|
||||
})
|
||||
|
||||
|
||||
class PrintingJobBatchAddParametersRequestSerializer(serializers.Serializer):
|
||||
"""批量补充参数请求序列化器"""
|
||||
printing_job_ids = serializers.ListField(
|
||||
child=serializers.IntegerField(),
|
||||
min_length=1,
|
||||
help_text='印染明细ID列表'
|
||||
)
|
||||
state_id = serializers.IntegerField(help_text='目标流程节点ID')
|
||||
parameters = serializers.DictField(
|
||||
child=serializers.CharField(allow_blank=True),
|
||||
help_text='要补充的工艺参数'
|
||||
)
|
||||
remark = serializers.CharField(required=False, default='', allow_blank=True, help_text='备注说明')
|
||||
|
||||
|
||||
def _validate_jobs_for_batch_add_parameters(printing_job_ids: list[int], state_id: int) -> dict:
|
||||
"""
|
||||
验证批量补充参数的 jobs 并返回相关数据
|
||||
|
||||
验证规则:
|
||||
1. 所有 job 必须存在
|
||||
2. 所有 job 必须属于同一个 printing_order
|
||||
3. 所有 job 必须有 business_object
|
||||
4. 所有 job 的 business_object 必须有对应 state_id 的 state_log(未撤销)
|
||||
|
||||
返回:
|
||||
{
|
||||
'jobs': QuerySet[PrintingJob],
|
||||
'printing_order': PrintingOrder,
|
||||
'printing_order_id': int,
|
||||
'state': State,
|
||||
'state_logs': dict[int, StateFlowRecord], # job_id -> state_log
|
||||
}
|
||||
"""
|
||||
from stateflow import models as stateflow_models
|
||||
|
||||
jobs = (
|
||||
printing_models.PrintingJob.objects
|
||||
.select_related('printing_order', 'business_object')
|
||||
.filter(id__in=printing_job_ids)
|
||||
)
|
||||
|
||||
found_ids = set(jobs.values_list('id', flat=True))
|
||||
missing_ids = [i for i in printing_job_ids if i not in found_ids]
|
||||
if missing_ids:
|
||||
raise serializers.ValidationError({
|
||||
'detail': f'以下 PrintingJob 不存在: {missing_ids}',
|
||||
'missing_jobs': missing_ids,
|
||||
})
|
||||
|
||||
# 验证同一订单
|
||||
order_ids = set(jobs.values_list('printing_order_id', flat=True))
|
||||
if len(order_ids) != 1:
|
||||
raise serializers.ValidationError({
|
||||
'detail': '所有 PrintingJob 必须属于同一个 PrintingOrder',
|
||||
})
|
||||
|
||||
printing_order_id = order_ids.pop()
|
||||
printing_order = printing_models.PrintingOrder.objects.get(id=printing_order_id)
|
||||
|
||||
# 验证 state 存在
|
||||
try:
|
||||
state = stateflow_models.State.objects.get(id=state_id)
|
||||
except stateflow_models.State.DoesNotExist:
|
||||
raise serializers.ValidationError({
|
||||
'detail': f'State ID {state_id} 不存在',
|
||||
})
|
||||
|
||||
# 验证所有 job 有 business_object 和对应的 state_log
|
||||
jobs_without_bo = []
|
||||
jobs_without_state_log = []
|
||||
state_logs = {} # job_id -> state_log
|
||||
|
||||
for job in jobs:
|
||||
if not job.business_object:
|
||||
jobs_without_bo.append(job.id)
|
||||
continue
|
||||
|
||||
# 查找对应 state_id 的 state_log(未撤销)
|
||||
state_log = job.business_object.state_logs.filter(
|
||||
state_id=state_id,
|
||||
is_cancelled=False
|
||||
).first()
|
||||
|
||||
if not state_log:
|
||||
jobs_without_state_log.append(job.id)
|
||||
else:
|
||||
state_logs[job.id] = state_log
|
||||
|
||||
if jobs_without_bo:
|
||||
raise serializers.ValidationError({
|
||||
'detail': f'以下 PrintingJob 没有流程实例 (business_object): {jobs_without_bo}',
|
||||
'missing_business_object': jobs_without_bo,
|
||||
})
|
||||
|
||||
if jobs_without_state_log:
|
||||
raise serializers.ValidationError({
|
||||
'detail': f'以下 PrintingJob 没有对应 state_id={state_id} 的状态流转记录(或已撤销): {jobs_without_state_log}',
|
||||
'missing_state_log': jobs_without_state_log,
|
||||
})
|
||||
|
||||
return {
|
||||
'jobs': jobs,
|
||||
'printing_order': printing_order,
|
||||
'printing_order_id': printing_order_id,
|
||||
'state': state,
|
||||
'state_logs': state_logs,
|
||||
}
|
||||
|
||||
|
||||
class PrintingJobBatchAddParametersView(APIView):
|
||||
"""
|
||||
批量补充工艺参数
|
||||
|
||||
为多个 PrintingJob 的已完成状态流转记录批量补充工艺参数。
|
||||
|
||||
POST /api/v2/printing-jobs/batch-add-parameters/
|
||||
|
||||
请求体:
|
||||
{
|
||||
"printing_job_ids": [101, 102, 103],
|
||||
"state_id": 7,
|
||||
"parameters": {
|
||||
"temperature": "26.0",
|
||||
"operator": "李四"
|
||||
},
|
||||
"remark": "批量补充参数备注"
|
||||
}
|
||||
|
||||
响应:
|
||||
{
|
||||
"detail": "批量补充参数成功",
|
||||
"batch_record_id": 15,
|
||||
"printing_order_id": 55,
|
||||
"printing_job_ids": [101, 102, 103],
|
||||
"state_id": 7,
|
||||
"state_name": "染色",
|
||||
"parameters": {...},
|
||||
"affected_count": 3
|
||||
}
|
||||
"""
|
||||
|
||||
permission_classes = [permissions.IsAuthenticated, IsPrintingFactory]
|
||||
|
||||
def post(self, request):
|
||||
srz = PrintingJobBatchAddParametersRequestSerializer(data=request.data)
|
||||
srz.is_valid(raise_exception=True)
|
||||
|
||||
payload = srz.validated_data
|
||||
printing_job_ids = payload['printing_job_ids']
|
||||
state_id = payload['state_id']
|
||||
parameters = payload['parameters']
|
||||
remark = payload.get('remark', '')
|
||||
|
||||
if not parameters:
|
||||
raise serializers.ValidationError({
|
||||
'detail': '参数不能为空',
|
||||
})
|
||||
|
||||
# 验证数据
|
||||
data = _validate_jobs_for_batch_add_parameters(printing_job_ids, state_id)
|
||||
|
||||
from stateflow import services as stateflow_services
|
||||
|
||||
# 全成功/全失败
|
||||
with transaction.atomic():
|
||||
# 创建批量操作记录
|
||||
record = printing_models.PrintingJobBatchAdvanceRecord.objects.create(
|
||||
printing_order=data['printing_order'],
|
||||
state=data['state'],
|
||||
created_by=request.user,
|
||||
parameters=parameters,
|
||||
only_parameters=True, # 标记为仅补充参数
|
||||
)
|
||||
record.printing_jobs.set(data['jobs'])
|
||||
|
||||
# 逐个补充参数
|
||||
for job in data['jobs']:
|
||||
state_log = data['state_logs'][job.id]
|
||||
stateflow_services.add_parameters_to_state_log(
|
||||
state_log,
|
||||
remark=remark,
|
||||
**parameters
|
||||
)
|
||||
|
||||
return Response({
|
||||
'detail': '批量补充参数成功',
|
||||
'batch_record_id': record.id,
|
||||
'printing_order_id': data['printing_order_id'],
|
||||
'printing_job_ids': [j.id for j in data['jobs']],
|
||||
'state_id': state_id,
|
||||
'state_name': data['state'].name,
|
||||
'parameters': parameters,
|
||||
'affected_count': len(data['jobs']),
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user