|
@@ -39,6 +39,37 @@ from django.db.models import Sum
|
|
from staff.models import ListModel as StaffListModel
|
|
from staff.models import ListModel as StaffListModel
|
|
logger = logging.getLogger(__name__)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
+# 托盘分类视图
|
|
|
|
+# 借助LocationContainerLink,其中
|
|
|
|
+# 库位-托盘关联表(记录实时存放关系)
|
|
|
|
+# class LocationContainerLink(models.Model):
|
|
|
|
+# location = models.ForeignKey(
|
|
|
|
+# LocationModel,
|
|
|
|
+# on_delete=models.CASCADE,
|
|
|
|
+# related_name='container_links',
|
|
|
|
+# verbose_name='库位'
|
|
|
|
+# )
|
|
|
|
+
|
|
|
|
+# container = models.ForeignKey(
|
|
|
|
+# ContainerListModel,
|
|
|
|
+# on_delete=models.CASCADE,
|
|
|
|
+# related_name='location_links',
|
|
|
|
+# verbose_name='关联托盘'
|
|
|
|
+# )
|
|
|
|
+
|
|
|
|
+# task_wcs = models.ForeignKey(ContainerWCSModel, on_delete=models.CASCADE, null=True, blank=True)
|
|
|
|
+# task_detail = models.ForeignKey(TaskModel, on_delete=models.CASCADE, null=True, blank=True)
|
|
|
|
+# put_time = models.DateTimeField(auto_now_add=True, verbose_name='上架时间')
|
|
|
|
+# operator = models.CharField(max_length=50, verbose_name='操作人')
|
|
|
|
+# is_active = models.BooleanField(default=True, verbose_name='是否有效')
|
|
|
|
+# 借助LocationContainerLink中的is_active字段,可以查询托盘是否在库位中,
|
|
|
|
+# 若is_active为True,则托盘在库位中,否则托盘不在库位中。同时,再增加字段来显示在库托盘中的存储的物料信息。
|
|
|
|
+# class containerclassViewSet(viewsets.ModelViewSet):
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
# 托盘流水汇总批次流水
|
|
# 托盘流水汇总批次流水
|
|
class batchLogModelViewSet(viewsets.ModelViewSet):
|
|
class batchLogModelViewSet(viewsets.ModelViewSet):
|
|
|
|
|
|
@@ -209,6 +240,8 @@ class ContainerListViewSet(viewsets.ModelViewSet):
|
|
else:
|
|
else:
|
|
return self.http_method_not_allowed(request=self.request)
|
|
return self.http_method_not_allowed(request=self.request)
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
def create(self, request, *args, **kwargs):
|
|
def create(self, request, *args, **kwargs):
|
|
# 创建托盘:托盘码五位数字(唯一),当前库位,目标库位,状态,最后操作时间
|
|
# 创建托盘:托盘码五位数字(唯一),当前库位,目标库位,状态,最后操作时间
|
|
|
|
|
|
@@ -252,6 +285,11 @@ class ContainerListViewSet(viewsets.ModelViewSet):
|
|
# 如果没有分页,返回完整结果(不推荐)
|
|
# 如果没有分页,返回完整结果(不推荐)
|
|
serializer = ContainerListGetSerializer(container_list, many=True)
|
|
serializer = ContainerListGetSerializer(container_list, many=True)
|
|
return Response(serializer.data, status=200)
|
|
return Response(serializer.data, status=200)
|
|
|
|
+
|
|
|
|
+ def update_container_categories(self, request, *args, **kwargs):
|
|
|
|
+ from .utils import update_container_categories_task
|
|
|
|
+ update_container_categories_task()
|
|
|
|
+ return Response({'message': '托盘分类更新任务已触发'}, status=200)
|
|
|
|
|
|
# wcs任务视图
|
|
# wcs任务视图
|
|
class WCSTaskViewSet(viewsets.ModelViewSet):
|
|
class WCSTaskViewSet(viewsets.ModelViewSet):
|
|
@@ -496,7 +534,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
container = data.get('container_code')
|
|
container = data.get('container_code')
|
|
start_location = data.get('start_location')
|
|
start_location = data.get('start_location')
|
|
target_location = data.get('target_location')
|
|
target_location = data.get('target_location')
|
|
- logger.info(f"请求托盘:{container},起始位置:{start_location},目标位置:{target_location}")
|
|
|
|
|
|
+ logger.info(f"移库请求托盘:{container},起始位置:{start_location},目标位置:{target_location}")
|
|
data_return = {}
|
|
data_return = {}
|
|
|
|
|
|
try:
|
|
try:
|
|
@@ -574,13 +612,89 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
|
)
|
|
)
|
|
|
|
|
|
|
|
+ def generate_out_task(self, request, *args, **kwargs):
|
|
|
|
+ data = self.request.data
|
|
|
|
+ container = data.get('container_code')
|
|
|
|
+ start_location = data.get('current_location')
|
|
|
|
+ target_location = data.get('target_location')
|
|
|
|
+ logger.info(f"出库请求托盘:{container},起始位置:{start_location},目标位置:{target_location}")
|
|
|
|
+ data_return = {}
|
|
|
|
+ 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)
|
|
|
|
+ # 检查是否已在目标位置
|
|
|
|
+ if target_location == str(container_obj.target_location) :
|
|
|
|
+ logger.info(f"托盘 {container} 已在目标位置")
|
|
|
|
+ data_return = {
|
|
|
|
+ 'code': '200',
|
|
|
|
+ 'message': '当前位置已是目标位置',
|
|
|
|
+ 'data': data
|
|
|
|
+ }
|
|
|
|
+ else:
|
|
|
|
+ # 生成任务
|
|
|
|
+ current_task = ContainerWCSModel.objects.filter(
|
|
|
|
+ container=container,
|
|
|
|
+ tasktype='outbound',
|
|
|
|
+ working = 1,
|
|
|
|
+
|
|
|
|
+ ).exclude(status=300).first()
|
|
|
|
+
|
|
|
|
+ if current_task:
|
|
|
|
+ data_return = {
|
|
|
|
+ 'code': '200',
|
|
|
|
+ 'message': '任务已存在,重新下发',
|
|
|
|
+ 'data': current_task.to_dict()
|
|
|
|
+ }
|
|
|
|
+ else:
|
|
|
|
+ # todo: 这里的入库操作记录里面的记录的数量不对
|
|
|
|
+ allocation_target_location, batch_info = AllocationService._out_allocation(start_location, target_location,container)
|
|
|
|
+ batch_id = batch_info['number']
|
|
|
|
+ if batch_info['class'] == 2:
|
|
|
|
+ self.generate_task_no_batch(container, start_location, allocation_target_location,batch_id,1,'outbound')
|
|
|
|
+ self.generate_container_operate_no_batch(container_obj, batch_id, allocation_target_location,"outbound")
|
|
|
|
+ elif batch_info['class'] == 3:
|
|
|
|
+ self.generate_task_no_batch(container, start_location, allocation_target_location,batch_id,1,'outbound')
|
|
|
|
+ self.generate_move_container_operate(container_obj, allocation_target_location,"outbound")
|
|
|
|
+ else:
|
|
|
|
+ self.generate_task(container, start_location, allocation_target_location,batch_id,1,'outbound') # 生成任务
|
|
|
|
+ self.generate_move_container_operate(container_obj, allocation_target_location,"outbound")
|
|
|
|
+
|
|
|
|
+ current_task = ContainerWCSModel.objects.get(
|
|
|
|
+ container=container,
|
|
|
|
+ tasktype='outbound',
|
|
|
|
+ working=1,
|
|
|
|
+ )
|
|
|
|
+ OutboundService.send_task_to_wcs(current_task)
|
|
|
|
+ data_return = {
|
|
|
|
+ 'code': '200',
|
|
|
|
+ 'message': '任务下发成功',
|
|
|
|
+ 'data': current_task.to_dict()
|
|
|
|
+ }
|
|
|
|
+ container_obj.target_location = allocation_target_location
|
|
|
|
+ container_obj.save()
|
|
|
|
+ if batch_info['class'] == 1 or batch_info['class'] == 3:
|
|
|
|
+ self.inport_update_task(current_task.id, container_obj.id)
|
|
|
|
+ http_status = status.HTTP_200_OK if data_return['code'] == '200' else status.HTTP_400_BAD_REQUEST
|
|
|
|
+ return Response(data_return, status=http_status)
|
|
|
|
|
|
|
|
+ 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 get_container_wcs(self, request, *args, **kwargs):
|
|
def get_container_wcs(self, request, *args, **kwargs):
|
|
data = self.request.data
|
|
data = self.request.data
|
|
container = data.get('container_number')
|
|
container = data.get('container_number')
|
|
current_location = data.get('current_location')
|
|
current_location = data.get('current_location')
|
|
- logger.info(f"请求托盘:{container},请求位置:{current_location}")
|
|
|
|
|
|
+ logger.info(f"入库请求托盘:{container},请求位置:{current_location}")
|
|
data_return = {}
|
|
data_return = {}
|
|
|
|
|
|
try:
|
|
try:
|
|
@@ -714,7 +828,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
- def generate_move_container_operate(self, container_obj, allocation_target_location):
|
|
|
|
|
|
+ def generate_move_container_operate(self, container_obj, allocation_target_location,operate_type="adjust"):
|
|
|
|
|
|
# 获取容器中所有有效的批次明细
|
|
# 获取容器中所有有效的批次明细
|
|
container_detaillist = ContainerDetailModel.objects.filter(
|
|
container_detaillist = ContainerDetailModel.objects.filter(
|
|
@@ -751,7 +865,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
container=container_obj,
|
|
container=container_obj,
|
|
goods_code=batch_obj.goods_code,
|
|
goods_code=batch_obj.goods_code,
|
|
goods_desc=batch_obj.goods_desc,
|
|
goods_desc=batch_obj.goods_desc,
|
|
- operation_type="adjust", # 操作类型改为移动
|
|
|
|
|
|
+ operation_type=operate_type, # 操作类型改为移动
|
|
batch_id=batch_obj.id,
|
|
batch_id=batch_obj.id,
|
|
goods_qty=goods_qty,
|
|
goods_qty=goods_qty,
|
|
goods_weight=goods_qty,
|
|
goods_weight=goods_qty,
|
|
@@ -779,24 +893,24 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
- def generate_container_operate_no_batch(self, container_obj, bound_number,allocation_target_location):
|
|
|
|
|
|
+ def generate_container_operate_no_batch(self, container_obj, bound_number,allocation_target_location,operate_type="inbound"):
|
|
|
|
|
|
ContainerOperationModel.objects.create(
|
|
ContainerOperationModel.objects.create(
|
|
month = int(timezone.now().strftime("%Y%m")),
|
|
month = int(timezone.now().strftime("%Y%m")),
|
|
container = container_obj,
|
|
container = container_obj,
|
|
goods_code = 'container',
|
|
goods_code = 'container',
|
|
goods_desc = '托盘组',
|
|
goods_desc = '托盘组',
|
|
- operation_type ="inbound",
|
|
|
|
|
|
+ operation_type =operate_type,
|
|
goods_qty = 1,
|
|
goods_qty = 1,
|
|
goods_weight = 0,
|
|
goods_weight = 0,
|
|
from_location = container_obj.current_location,
|
|
from_location = container_obj.current_location,
|
|
to_location= allocation_target_location,
|
|
to_location= allocation_target_location,
|
|
timestamp=timezone.now(),
|
|
timestamp=timezone.now(),
|
|
- memo=f"WCS入库: 批次: {bound_number}, 数量: 1"
|
|
|
|
|
|
+ memo=f"WCSs手动出库库: 批次: {bound_number}, 数量: 1"
|
|
|
|
|
|
)
|
|
)
|
|
|
|
|
|
- def generate_task(self, container, current_location, target_location,batch_id,location_c_number):
|
|
|
|
|
|
+ def generate_task(self, container, current_location, target_location,batch_id,location_c_number,tasktype='inbound'):
|
|
batch = BoundBatchModel.objects.filter(bound_number=batch_id).first()
|
|
batch = BoundBatchModel.objects.filter(bound_number=batch_id).first()
|
|
batch_detail = BoundDetailModel.objects.filter(bound_batch=batch).first()
|
|
batch_detail = BoundDetailModel.objects.filter(bound_batch=batch).first()
|
|
if not batch:
|
|
if not batch:
|
|
@@ -814,7 +928,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
'current_location': current_location,
|
|
'current_location': current_location,
|
|
'month': timezone.now().strftime('%Y%m'),
|
|
'month': timezone.now().strftime('%Y%m'),
|
|
'target_location': target_location,
|
|
'target_location': target_location,
|
|
- 'tasktype': 'inbound',
|
|
|
|
|
|
+ 'tasktype': tasktype,
|
|
'status': 103,
|
|
'status': 103,
|
|
'is_delete': False
|
|
'is_delete': False
|
|
}
|
|
}
|
|
@@ -838,7 +952,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
data_tosave['tasknumber'] = number_id
|
|
data_tosave['tasknumber'] = number_id
|
|
ContainerWCSModel.objects.create(**data_tosave)
|
|
ContainerWCSModel.objects.create(**data_tosave)
|
|
|
|
|
|
- def generate_task_no_batch(self, container, current_location, target_location,batch_id,location_c_number):
|
|
|
|
|
|
+ def generate_task_no_batch(self, container, current_location, target_location,batch_id,location_c_number,tasktype='inbound'):
|
|
|
|
|
|
data_tosave = {
|
|
data_tosave = {
|
|
'container': container,
|
|
'container': container,
|
|
@@ -852,7 +966,7 @@ class ContainerWCSViewSet(viewsets.ModelViewSet):
|
|
'current_location': current_location,
|
|
'current_location': current_location,
|
|
'month': timezone.now().strftime('%Y%m'),
|
|
'month': timezone.now().strftime('%Y%m'),
|
|
'target_location': target_location,
|
|
'target_location': target_location,
|
|
- 'tasktype': 'inbound',
|
|
|
|
|
|
+ 'tasktype': tasktype,
|
|
'status': 103,
|
|
'status': 103,
|
|
'is_delete': False
|
|
'is_delete': False
|
|
}
|
|
}
|
|
@@ -2287,7 +2401,7 @@ class OutTaskViewSet(ViewSet):
|
|
left_qty += add_qty
|
|
left_qty += add_qty
|
|
last_out_qty = cd.goods_out_qty
|
|
last_out_qty = cd.goods_out_qty
|
|
cd.goods_out_qty += add_qty
|
|
cd.goods_out_qty += add_qty
|
|
- print(f"{left_qty/25} 更新托盘 {cd.container.container_code} 批次 {cd.batch_id} 出库数量: {cd.goods_out_qty}")
|
|
|
|
|
|
+ # print(f"{left_qty/25} 更新托盘 {cd.container.container_code} 批次 {cd.batch_id} 出库数量: {cd.goods_out_qty}")
|
|
|
|
|
|
cd.save()
|
|
cd.save()
|
|
|
|
|