|
@@ -16,7 +16,7 @@ import logging
|
|
|
from rest_framework import status
|
|
|
from .models import ContainerListModel,ContainerDetailModel,ContainerOperationModel,ContainerWCSModel,TaskModel
|
|
|
from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel,OutBoundDetailModel
|
|
|
-from bin.views import LocationAllocation
|
|
|
+from bin.views import LocationAllocation,base_location
|
|
|
from bin.models import LocationModel,LocationContainerLink
|
|
|
# from .files import FileListRenderCN, FileDetailRenderCN
|
|
|
|
|
@@ -159,6 +159,88 @@ class TaskViewSet(viewsets.ModelViewSet):
|
|
|
headers = self.get_success_headers(serializer.data)
|
|
|
return Response(serializer.data, status=200, headers=headers)
|
|
|
|
|
|
+class TaskRollbackMixin:
|
|
|
+ @transaction.atomic
|
|
|
+ def rollback_task(self, request, task_id, *args, **kwargs):
|
|
|
+ """
|
|
|
+ 撤销入库任务并回滚相关状态
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ # 获取任务实例并锁定数据库记录
|
|
|
+ task = ContainerWCSModel.objects.select_for_update().get(taskid=task_id)
|
|
|
+ container_code = task.container
|
|
|
+ target_location = task.target_location
|
|
|
+ batch = task.batch
|
|
|
+
|
|
|
+ # 初始化库位分配器
|
|
|
+ allocator = LocationAllocation()
|
|
|
+
|
|
|
+ # ==================== 库位状态回滚 ====================
|
|
|
+ # 解析目标库位信息(格式:仓库代码-行-列-层)
|
|
|
+ try:
|
|
|
+ warehouse_code, row, col, layer = target_location.split('-')
|
|
|
+ location = LocationModel.objects.get(
|
|
|
+ warehouse_code=warehouse_code,
|
|
|
+ row=int(row),
|
|
|
+ col=int(col),
|
|
|
+ layer=int(layer)
|
|
|
+ )
|
|
|
+
|
|
|
+ # 回滚库位状态到可用状态
|
|
|
+ allocator.update_location_status(location.location_code, 'available')
|
|
|
+
|
|
|
+ # 更新库位组状态(需要根据实际逻辑实现)
|
|
|
+ allocator.update_location_group_status(location.location_code)
|
|
|
+
|
|
|
+ # 解除库位与托盘的关联
|
|
|
+ allocator.update_location_container_link(location.location_code, None)
|
|
|
+
|
|
|
+ # 清除库位组的批次关联
|
|
|
+ allocator.update_location_group_batch(location, None)
|
|
|
+
|
|
|
+ except (ValueError, LocationModel.DoesNotExist) as e:
|
|
|
+ logger.error(f"库位解析失败: {str(e)}")
|
|
|
+ raise Exception("关联库位信息无效")
|
|
|
+
|
|
|
+ # ==================== 批次状态回滚 ====================
|
|
|
+ if batch:
|
|
|
+ # 将批次状态恢复为未处理状态(假设原状态为1)
|
|
|
+ allocator.update_batch_status(batch.bound_number, '1')
|
|
|
+
|
|
|
+ # ==================== 容器状态回滚 ====================
|
|
|
+ container_obj = ContainerListModel.objects.get(container_code=container_code)
|
|
|
+
|
|
|
+ # 恢复容器详细状态为初始状态(假设原状态为1)
|
|
|
+ allocator.update_container_detail_status(container_code, 1)
|
|
|
+
|
|
|
+ # 恢复容器的目标位置为当前所在位置
|
|
|
+ container_obj.target_location = task.current_location
|
|
|
+ container_obj.save()
|
|
|
+
|
|
|
+ # ==================== 删除任务记录 ====================
|
|
|
+ task.delete()
|
|
|
+
|
|
|
+ # ==================== 其他关联清理 ====================
|
|
|
+ # 如果有其他关联数据(如inport_update_task的操作),在此处添加清理逻辑
|
|
|
+
|
|
|
+ return Response(
|
|
|
+ {'code': '200', 'message': '任务回滚成功', 'data': None},
|
|
|
+ status=status.HTTP_200_OK
|
|
|
+ )
|
|
|
+
|
|
|
+ except ContainerWCSModel.DoesNotExist:
|
|
|
+ logger.warning(f"任务不存在: {task_id}")
|
|
|
+ return Response(
|
|
|
+ {'code': '404', 'message': '任务不存在', 'data': None},
|
|
|
+ status=status.HTTP_404_NOT_FOUND
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"任务回滚失败: {str(e)}", exc_info=True)
|
|
|
+ return Response(
|
|
|
+ {'code': '500', 'message': '服务器内部错误', 'data': None},
|
|
|
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
|
+ )
|
|
|
|
|
|
class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
"""
|
|
@@ -181,11 +263,6 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
container = data.get('container_number')
|
|
|
current_location = data.get('current_location')
|
|
|
logger.info(f"请求托盘:{container},请求位置:{current_location}")
|
|
|
- if current_location =="203":
|
|
|
- current_location ="in1"
|
|
|
- elif current_location=="103":
|
|
|
- current_location="in2"
|
|
|
-
|
|
|
data_return = {}
|
|
|
|
|
|
try:
|
|
@@ -268,6 +345,12 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
|
|
|
return
|
|
|
print(f"[7]库位和托盘的关联关系更新成功!")
|
|
|
+
|
|
|
+ update_location_container_detail = allocator.update_container_detail_status(container_code,2) # 更新库位和托盘的关联关系
|
|
|
+ if not update_location_container_detail:
|
|
|
+ print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
|
|
|
+ return
|
|
|
+ print(f"[8]托盘的关联关系更新成功!")
|
|
|
|
|
|
|
|
|
allocation_target_location = (
|
|
@@ -276,7 +359,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
+ f"{int(location_list_cnumber.col):02d}" + '-'
|
|
|
+ f"{int(location_list_cnumber.layer):02d}"
|
|
|
)
|
|
|
- batch_id = LocationAllocation.get_batch(container_code)
|
|
|
+ batch_id = allocator.get_batch(container_code)
|
|
|
self.generate_task(container, current_location, allocation_target_location,batch_id,location_list_cnumber.c_number) # 生成任务
|
|
|
current_task = ContainerWCSModel.objects.get(
|
|
|
container=container,
|
|
@@ -328,15 +411,15 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
|
|
|
# 生成唯一递增的 taskid
|
|
|
last_task = ContainerWCSModel.objects.filter(
|
|
|
- month=data_tosave['month'],
|
|
|
- tasktype='inbound'
|
|
|
+ month=data_tosave['month'],
|
|
|
+
|
|
|
).order_by('-taskid').first()
|
|
|
|
|
|
if last_task:
|
|
|
last_id = int(last_task.taskid.split('-')[-1])
|
|
|
- new_id = f"{last_id + 1:04}"
|
|
|
+ new_id = f"{last_id + 1:05}"
|
|
|
else:
|
|
|
- new_id = "0001"
|
|
|
+ new_id = "00001"
|
|
|
|
|
|
data_tosave['taskid'] = f"inbound-{data_tosave['month']}-{new_id}"
|
|
|
logger.info(f"生成入库任务: {data_tosave['taskid']}")
|
|
@@ -346,166 +429,199 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
|
|
|
def update_container_wcs(self, request, *args, **kwargs):
|
|
|
data = self.request.data
|
|
|
- container = data.get('container_number')
|
|
|
- current_location = data.get('current_location')
|
|
|
- taskNumber = data.get('taskNumber')
|
|
|
-
|
|
|
-
|
|
|
- logger.info(f"请求托盘:{container},请求位置:{current_location}")
|
|
|
- if current_location =="203":
|
|
|
- current_location ="in1"
|
|
|
- elif current_location=="103":
|
|
|
- current_location="in2"
|
|
|
- data_return = {}
|
|
|
+ logger.info(f"请求托盘:{data.get('container_number')}, 请求位置:{data.get('current_location')}, 任务号:{data.get('taskNumber')}")
|
|
|
|
|
|
try:
|
|
|
- container_obj = ContainerListModel.objects.filter(container_code=container).first()
|
|
|
- if not container_obj:
|
|
|
- data_return = {
|
|
|
- 'code': '400',
|
|
|
- 'message': '托盘编码不存在',
|
|
|
- 'data': data
|
|
|
- }
|
|
|
- return Response(data_return, status=status.HTTP_400_BAD_REQUEST)
|
|
|
-
|
|
|
- # 更新容器数据(部分更新)
|
|
|
- serializer = ContainerListPostSerializer(
|
|
|
- container_obj,
|
|
|
- data=data,
|
|
|
- partial=True # 允许部分字段更新
|
|
|
- )
|
|
|
- serializer.is_valid(raise_exception=True)
|
|
|
- serializer.save()
|
|
|
-
|
|
|
- # 检查是否已在目标位置
|
|
|
- if current_location == str(container_obj.target_location):
|
|
|
- logger.info(f"托盘 {container} 已在目标位置")
|
|
|
- data_return = {
|
|
|
- 'code': '200',
|
|
|
- 'message': '当前位置已是目标位置',
|
|
|
- 'data': data
|
|
|
- }
|
|
|
-
|
|
|
- allocator = LocationAllocation() # 创建实例
|
|
|
- location_row = int(container_obj.target_location.split('-')[1])
|
|
|
- location_col = int(container_obj.target_location.split('-')[2])
|
|
|
- location_layer = int(container_obj.target_location.split('-')[3])
|
|
|
- coordinate = f"{location_row}-{location_col}-{location_layer}"
|
|
|
- print(f"坐标:{coordinate}")
|
|
|
- location_code = LocationModel.objects.filter(coordinate=coordinate).first().location_code
|
|
|
- container_code = container
|
|
|
- update_location_status = allocator.update_location_status(location_code, 'occupied') # 更新库位状态
|
|
|
- if not update_location_status:
|
|
|
- print("❌ 库位状态更新失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[6]WCS到位,库位状态更新成功!")
|
|
|
-
|
|
|
- update_location_container_link = allocator.update_location_container_link(location_code, container_code) # 更新库位和托盘的关联关系
|
|
|
- if not update_location_container_link:
|
|
|
- print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[7]库位和托盘的关联关系更新成功!")
|
|
|
-
|
|
|
+ # 前置校验
|
|
|
+ container_obj, error_response = self.validate_container(data)
|
|
|
+ if error_response:
|
|
|
+ return error_response
|
|
|
+
|
|
|
+ # 更新容器数据
|
|
|
+ if not self.update_container_data(container_obj, data):
|
|
|
+ return Response({'code': '400', 'message': '数据更新失败', 'data': data},
|
|
|
+ status=status.HTTP_400_BAD_REQUEST)
|
|
|
+
|
|
|
+ # 处理位置逻辑
|
|
|
+ if self.is_already_at_target(container_obj, data.get('current_location')):
|
|
|
+ return self.handle_target_reached(container_obj, data)
|
|
|
else:
|
|
|
- current_task = ContainerWCSModel.objects.filter(
|
|
|
- container=container,
|
|
|
- tasktype='inbound'
|
|
|
- ).first()
|
|
|
+ return self.handle_new_allocation(container_obj, data)
|
|
|
|
|
|
- if current_task:
|
|
|
-
|
|
|
- data_return = {
|
|
|
- 'code': '200',
|
|
|
- 'message': '任务已存在,重新下发',
|
|
|
- 'data': current_task.to_dict()
|
|
|
- }
|
|
|
- else:
|
|
|
- # 库位分配
|
|
|
- container_code = container
|
|
|
- print(f"开始生成库位,托盘编码:{container_code}")
|
|
|
- allocator = LocationAllocation() # 创建实例
|
|
|
-
|
|
|
- location_list_cnumber = allocator.get_location_by_status(container_code, current_location) # 获取库位列表
|
|
|
- if not location_list_cnumber:
|
|
|
- print("❌ 通用库位获取失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[1]库位:{location_list_cnumber}")
|
|
|
-
|
|
|
- update_location_status = allocator.update_location_status(location_list_cnumber.location_code, 'reserved') # 更新库位状态
|
|
|
- if not update_location_status:
|
|
|
- print("❌ 库位状态更新失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[2]发送任务,库位状态更新成功!")
|
|
|
- update_location_group_status = allocator.update_location_group_status(location_list_cnumber.location_code) # 更新库位组状态
|
|
|
- if not update_location_group_status:
|
|
|
- print("❌ 库位组状态更新失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[3]库位组状态更新成功!")
|
|
|
-
|
|
|
- update_batch_status = allocator.update_batch_status(container_code, '2') # 更新批次状态
|
|
|
- if not update_batch_status:
|
|
|
- print("❌ 批次状态更新失败,请检查批次号")
|
|
|
- return
|
|
|
- print(f"[4]批次状态更新成功!")
|
|
|
-
|
|
|
- update_location_group_batch = allocator.update_location_group_batch(location_list_cnumber, container_code) # 更新库位组的批次
|
|
|
- if not update_location_group_batch:
|
|
|
- print("❌ 库位组批次更新失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[5]库位组批次更新成功!")
|
|
|
-
|
|
|
-
|
|
|
- update_location_container_link = allocator.update_location_container_link(location_list_cnumber.location_code, container_code) # 更新库位和托盘的关联关系
|
|
|
- if not update_location_container_link:
|
|
|
- print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
|
|
|
- return
|
|
|
- print(f"[7]库位和托盘的关联关系更新成功!")
|
|
|
-
|
|
|
- # update_location_status = allocator.update_location_status(location_list_cnumber.location_code, 'occupied') # 更新库位状态
|
|
|
- # if not update_location_status:
|
|
|
- # print("❌ 库位状态更新失败,请检查托盘编码")
|
|
|
- # return
|
|
|
- # print(f"[6]WCS到位,库位状态更新成功!")
|
|
|
-
|
|
|
- # update_location_container_link = allocator.update_location_container_link(location_list_cnumber.location_code, container_code) # 更新库位和托盘的关联关系
|
|
|
- # if not update_location_container_link:
|
|
|
- # print("❌ 库位和托盘的关联关系更新失败,请检查托盘编码")
|
|
|
- # return
|
|
|
- # print(f"[7]库位和托盘的关联关系更新成功!")
|
|
|
- allocation_target_location = (
|
|
|
- location_list_cnumber.warehouse_code + '-'
|
|
|
- + f"{int(location_list_cnumber.row):02d}" + '-' # 关键修改点
|
|
|
- + f"{int(location_list_cnumber.col):02d}" + '-'
|
|
|
- + f"{int(location_list_cnumber.layer):02d}"
|
|
|
- )
|
|
|
- batch_id = allocator.get_batch(container_code)
|
|
|
- self.generate_task(container, current_location, allocation_target_location,batch_id,location_list_cnumber.c_number) # 生成任务
|
|
|
- current_task = ContainerWCSModel.objects.get(
|
|
|
- container=container,
|
|
|
- tasktype='inbound'
|
|
|
- )
|
|
|
-
|
|
|
- data_return = {
|
|
|
- 'code': '200',
|
|
|
- 'message': '任务下发成功',
|
|
|
- 'data': current_task.to_dict()
|
|
|
- }
|
|
|
- container_obj.target_location = allocation_target_location
|
|
|
- container_obj.save()
|
|
|
-
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
|
|
|
+ return Response({'code': '500', 'message': '服务器内部错误', 'data': None},
|
|
|
+ status=status.HTTP_500_INTERNAL_SERVER_ERROR)
|
|
|
|
|
|
- self.inport_update_task(current_task.id, container_obj.id)
|
|
|
+ # ---------- 辅助函数 ----------
|
|
|
+ def validate_container(self, data):
|
|
|
+ """验证容器是否存在"""
|
|
|
+ container = data.get('container_number')
|
|
|
+ container_obj = ContainerListModel.objects.filter(container_code=container).first()
|
|
|
+ if not container_obj:
|
|
|
+ return None, Response({
|
|
|
+ 'code': '400',
|
|
|
+ 'message': '托盘编码不存在',
|
|
|
+ 'data': data
|
|
|
+ }, status=status.HTTP_400_BAD_REQUEST)
|
|
|
+ return container_obj, None
|
|
|
+
|
|
|
+ def update_container_data(self, container_obj, data):
|
|
|
+ """更新容器数据"""
|
|
|
+ serializer = ContainerListPostSerializer(
|
|
|
+ container_obj,
|
|
|
+ data=data,
|
|
|
+ partial=True
|
|
|
+ )
|
|
|
+ if serializer.is_valid():
|
|
|
+ serializer.save()
|
|
|
+ return True
|
|
|
+ return False
|
|
|
+
|
|
|
+ def is_already_at_target(self, container_obj, current_location):
|
|
|
+ """检查是否已在目标位置"""
|
|
|
+ return current_location == str(container_obj.target_location)
|
|
|
+
|
|
|
+ def handle_target_reached(self, container_obj, data):
|
|
|
+ """处理已到达目标位置的逻辑"""
|
|
|
+ logger.info(f"托盘 {container_obj.container_code} 已在目标位置")
|
|
|
+ task = self.get_task_by_tasknumber(data)
|
|
|
+ self.update_pressure_values(task, container_obj)
|
|
|
+ task = self.process_task_completion(data)
|
|
|
+ if not task:
|
|
|
+ return Response({'code': '400', 'message': '任务不存在', 'data': data},
|
|
|
+ status=status.HTTP_400_BAD_REQUEST)
|
|
|
+ if task and task.tasktype == 'inbound':
|
|
|
+ self.update_storage_system(container_obj)
|
|
|
+
|
|
|
+ if task and task.tasktype == 'outbound':
|
|
|
+ OutboundService.process_next_task()
|
|
|
+
|
|
|
+ return Response({
|
|
|
+ 'code': '200',
|
|
|
+ 'message': '当前位置已是目标位置',
|
|
|
+ 'data': data
|
|
|
+ }, status=status.HTTP_200_OK)
|
|
|
|
|
|
+ def get_task_by_tasknumber(self, data):
|
|
|
+
|
|
|
+ taskNumber = data.get('taskNumber') + 20000000000
|
|
|
+ task = ContainerWCSModel.objects.filter(tasknumber=taskNumber).first()
|
|
|
+ if task:
|
|
|
+ return task
|
|
|
+ else:
|
|
|
+ return None
|
|
|
|
|
|
- http_status = status.HTTP_200_OK if data_return['code'] == '200' else status.HTTP_400_BAD_REQUEST
|
|
|
- return Response(data_return, status=http_status)
|
|
|
+ def process_task_completion(self, data):
|
|
|
+ """处理任务完成状态"""
|
|
|
+ taskNumber = data.get('taskNumber') + 20000000000
|
|
|
+ task = ContainerWCSModel.objects.filter(tasknumber=taskNumber).first()
|
|
|
+ if task:
|
|
|
+ task.status = 300
|
|
|
+ task.working = 0
|
|
|
+ task.save()
|
|
|
+
|
|
|
+ return task
|
|
|
+
|
|
|
+ def update_pressure_values(self, task, container_obj):
|
|
|
+ """更新压力值计算"""
|
|
|
+ if task and task.tasktype in ['inbound']:
|
|
|
+ base_location_obj = base_location.objects.get(id=1)
|
|
|
+ layer = int(container_obj.target_location.split('-')[-1])
|
|
|
+ pressure_field = f"layer{layer}_pressure"
|
|
|
+ logger.info(f"更新压力值,压力字段:{pressure_field}")
|
|
|
+ current_pressure = getattr(base_location_obj, pressure_field, 0)
|
|
|
+ updated_pressure = max(current_pressure - task.working, 0)
|
|
|
+ setattr(base_location_obj, pressure_field, updated_pressure)
|
|
|
+ base_location_obj.save()
|
|
|
+
|
|
|
+ def update_storage_system(self, container_obj):
|
|
|
+ """更新仓储系统状态"""
|
|
|
+ allocator = LocationAllocation()
|
|
|
+ location_code = self.get_location_code(container_obj.target_location)
|
|
|
+
|
|
|
+ # 链式更新操作
|
|
|
+ update_operations = [
|
|
|
+ (allocator.update_location_status, location_code, 'occupied'),
|
|
|
+ (allocator.update_location_container_link, location_code, container_obj.container_code),
|
|
|
+ (allocator.update_container_detail_status, container_obj.container_code, 2)
|
|
|
+ ]
|
|
|
+
|
|
|
+ for func, *args in update_operations:
|
|
|
+ if not func(*args):
|
|
|
+ logger.error(f"操作失败: {func.__name__}")
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+
|
|
|
+ def get_location_code(self, target_location):
|
|
|
+ """从目标位置解析获取位置编码"""
|
|
|
+ parts = target_location.split('-')
|
|
|
+ coordinate = f"{int(parts[1])}-{int(parts[2])}-{int(parts[3])}"
|
|
|
+ return LocationModel.objects.filter(coordinate=coordinate).first().location_code
|
|
|
+
|
|
|
+ def handle_new_allocation(self, container_obj, data):
|
|
|
+ """处理新库位分配逻辑"""
|
|
|
+ allocator = LocationAllocation()
|
|
|
+ container_code = container_obj.container_code
|
|
|
+
|
|
|
+ # 获取并验证库位分配
|
|
|
+ location = allocator.get_location_by_status(container_code, data.get('current_location'))
|
|
|
+ if not location or not self.perform_initial_allocation(allocator, location, container_code):
|
|
|
+ return Response({'code': '400', 'message': '库位分配失败', 'data': data},
|
|
|
+ status=status.HTTP_400_BAD_REQUEST)
|
|
|
+
|
|
|
+ # 生成目标位置并更新容器
|
|
|
+ target_location = self.generate_target_location(location)
|
|
|
+ container_obj.target_location = target_location
|
|
|
+ container_obj.save()
|
|
|
+
|
|
|
+ # 创建任务并返回响应
|
|
|
+ task = self.create_inbound_task(container_code, data, target_location, location)
|
|
|
+ return Response({
|
|
|
+ 'code': '200',
|
|
|
+ 'message': '任务下发成功',
|
|
|
+ 'data': task.to_dict()
|
|
|
+ }, status=status.HTTP_200_OK)
|
|
|
+
|
|
|
+ def perform_initial_allocation(self, allocator, location, container_code):
|
|
|
+ """执行初始库位分配操作"""
|
|
|
+ operations = [
|
|
|
+ (allocator.update_location_status, location.location_code, 'reserved'),
|
|
|
+ (allocator.update_location_group_status, location.location_code),
|
|
|
+ (allocator.update_batch_status, container_code, '2'),
|
|
|
+ (allocator.update_location_group_batch, location, container_code),
|
|
|
+ (allocator.update_location_container_link, location.location_code, container_code),
|
|
|
+ (allocator.update_container_detail_status, container_code, 2)
|
|
|
+ ]
|
|
|
+
|
|
|
+ for func, *args in operations:
|
|
|
+ if not func(*args):
|
|
|
+ logger.error(f"分配操作失败: {func.__name__}")
|
|
|
+ return False
|
|
|
+ return True
|
|
|
+
|
|
|
+ def generate_target_location(self, location):
|
|
|
+ """生成目标位置字符串"""
|
|
|
+ return (
|
|
|
+ f"{location.warehouse_code}-"
|
|
|
+ f"{int(location.row):02d}-"
|
|
|
+ f"{int(location.col):02d}-"
|
|
|
+ f"{int(location.layer):02d}"
|
|
|
+ )
|
|
|
|
|
|
- except Exception as e:
|
|
|
- logger.error(f"处理请求时发生错误: {str(e)}", exc_info=True)
|
|
|
- return Response(
|
|
|
- {'code': '500', 'message': '服务器内部错误', 'data': None},
|
|
|
- status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
|
- )
|
|
|
+ def create_inbound_task(self, container_code, data, target_location, location):
|
|
|
+ """创建入库任务"""
|
|
|
+ batch_id = LocationAllocation().get_batch(container_code)
|
|
|
+ self.generate_task(
|
|
|
+ container_code,
|
|
|
+ data.get('current_location'),
|
|
|
+ target_location,
|
|
|
+ batch_id,
|
|
|
+ location.c_number
|
|
|
+ )
|
|
|
+ task = ContainerWCSModel.objects.get(container=container_code, tasktype='inbound')
|
|
|
+ self.inport_update_task(task.id, container_code)
|
|
|
+ return task
|
|
|
|
|
|
@transaction.atomic
|
|
|
def inport_update_task(self, wcs_id,container_id):
|
|
@@ -821,7 +937,7 @@ class OutboundService:
|
|
|
month=int(month)
|
|
|
).order_by('-sequence').first()
|
|
|
sequence = last_task.sequence + 1 if last_task else 1
|
|
|
- return f"outbound-{month}-{sequence:04d}"
|
|
|
+ return f"outbound-{month}-{sequence:05d}"
|
|
|
|
|
|
# @staticmethod
|
|
|
# def send_task_to_wcs(task):
|
|
@@ -874,13 +990,15 @@ class OutboundService:
|
|
|
"month": task.month,
|
|
|
"message": task.message,
|
|
|
"status": task.status,
|
|
|
- "taskNumber": task.tasknumber,
|
|
|
+ "taskNumber": task.tasknumber-20000000000,
|
|
|
"order_number":task.order_number,
|
|
|
"sequence":task.sequence
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+ container_obj = ContainerListModel.objects.filter(container_code=task.container).first()
|
|
|
+ container_obj.target_location = task.target_location
|
|
|
+ container_obj.save()
|
|
|
# 创建并启动线程
|
|
|
thread = threading.Thread(
|
|
|
target=OutboundService._async_send_handler,
|
|
@@ -960,10 +1078,10 @@ class OutboundService:
|
|
|
sequence=index,
|
|
|
order_number = container['location_c_number'],
|
|
|
priority=100,
|
|
|
- tasknumber = month*10000+tasknumber_index+tasknumber,
|
|
|
+ tasknumber = month*100000+tasknumber_index+tasknumber,
|
|
|
container=container_obj.container_code,
|
|
|
current_location=container_obj.current_location,
|
|
|
- target_location="103",
|
|
|
+ target_location="203",
|
|
|
tasktype="outbound",
|
|
|
month=int(timezone.now().strftime("%Y%m")),
|
|
|
message="等待出库",
|
|
@@ -1028,6 +1146,7 @@ class OutTaskViewSet(viewsets.ModelViewSet):
|
|
|
"""
|
|
|
# fun:get_out_task:下发出库任务
|
|
|
# fun:get_batch_count_by_boundlist:获取出库申请下的批次数量
|
|
|
+ # fun:generate_location_by_demand:根据出库需求生成出库任务
|
|
|
"""
|
|
|
|
|
|
# authentication_classes = [] # 禁用所有认证类
|
|
@@ -1061,6 +1180,7 @@ class OutTaskViewSet(viewsets.ModelViewSet):
|
|
|
logger.error(f"任务生成失败: {str(e)}")
|
|
|
return Response({"code": "500", "msg": str(e)}, status=500)
|
|
|
|
|
|
+ # 获取出库需求
|
|
|
def get_batch_count_by_boundlist(self,bound_list_id):
|
|
|
try:
|
|
|
bound_list_obj_all = OutBoundDetailModel.objects.filter(bound_list=bound_list_id).all()
|
|
@@ -1136,7 +1256,7 @@ class OutTaskViewSet(viewsets.ModelViewSet):
|
|
|
try:
|
|
|
return_location =[]
|
|
|
for demand_id, demand_qty in demand_list.items():
|
|
|
- container_list = self.get_location_by_status_and_batch(1, demand_id)
|
|
|
+ container_list = self.get_location_by_status_and_batch(2, demand_id)
|
|
|
if not container_list:
|
|
|
return {"code": "500", "msg": f"批次 {demand_id} 不存在"}
|
|
|
container_id_list = container_list.keys()
|
|
@@ -1152,7 +1272,7 @@ class OutTaskViewSet(viewsets.ModelViewSet):
|
|
|
)
|
|
|
current_qty = 0
|
|
|
for container in order:
|
|
|
- container_detail_obj = ContainerDetailModel.objects.filter(container_id=container['container_number'],batch_id=demand_id,status=1).all()
|
|
|
+ container_detail_obj = ContainerDetailModel.objects.filter(container_id=container['container_number'],batch_id=demand_id,status=2).all()
|
|
|
if not container_detail_obj:
|
|
|
return {"code": "500", "msg": f"托盘上无该批次,请检查{container['container_number']} 不存在"}
|
|
|
goods_qty = 0
|