|  | @@ -11,7 +11,7 @@ from django.utils import timezone
 | 
	
		
			
				|  |  |  from django.db import transaction
 | 
	
		
			
				|  |  |  import logging
 | 
	
		
			
				|  |  |  from rest_framework import status
 | 
	
		
			
				|  |  | -from .models import DeviceModel,LocationModel,LocationGroupModel,LocationContainerLink,LocationChangeLog
 | 
	
		
			
				|  |  | +from .models import DeviceModel,LocationModel,LocationGroupModel,LocationContainerLink,LocationChangeLog,alloction_pre
 | 
	
		
			
				|  |  |  from bound.models import BoundBatchModel,BoundDetailModel,BoundListModel
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -26,15 +26,189 @@ logger = logging.getLogger(__name__)
 | 
	
		
			
				|  |  |  # 库位分配
 | 
	
		
			
				|  |  |  # 入库规则函数
 | 
	
		
			
				|  |  |  # 逻辑根据批次下的托盘数目来找满足区间范围的库位,按照优先级排序,
 | 
	
		
			
				|  |  | +     
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +class locationViewSet(viewsets.ModelViewSet):
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +        retrieve:
 | 
	
		
			
				|  |  | +            Response a data list(get)
 | 
	
		
			
				|  |  | +            list:
 | 
	
		
			
				|  |  | +            Response a data list(all)
 | 
	
		
			
				|  |  | +        create:
 | 
	
		
			
				|  |  | +            Create a data line(post)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        delete:
 | 
	
		
			
				|  |  | +            Delete a data line(delete)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +    # authentication_classes = []  # 禁用所有认证类
 | 
	
		
			
				|  |  | +    # permission_classes = [AllowAny]  # 允许任意访问
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    pagination_class = MyPageNumberPagination   
 | 
	
		
			
				|  |  | +    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
 | 
	
		
			
				|  |  | +    ordering_fields = ['id', "create_time", "update_time", ]
 | 
	
		
			
				|  |  | +    filter_class = LocationFilter
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def get_project(self):
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            id = self.kwargs.get('pk')
 | 
	
		
			
				|  |  | +            return id
 | 
	
		
			
				|  |  | +        except:
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def get_queryset(self):
 | 
	
		
			
				|  |  | +        id = self.get_project()
 | 
	
		
			
				|  |  | +        if self.request.user:
 | 
	
		
			
				|  |  | +            if id is None:
 | 
	
		
			
				|  |  | +                return LocationModel.objects.filter()
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                return LocationModel.objects.filter( id=id)
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            return LocationModel.objects.none()
 | 
	
		
			
				|  |  | +    def get_serializer_class(self):
 | 
	
		
			
				|  |  | +        if self.action == 'list':
 | 
	
		
			
				|  |  | +            return LocationListSerializer
 | 
	
		
			
				|  |  | +        elif self.action == 'update':
 | 
	
		
			
				|  |  | +            return LocationPostSerializer
 | 
	
		
			
				|  |  | +        elif self.action =='retrieve':
 | 
	
		
			
				|  |  | +            return LocationListSerializer
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def update(self, request, *args, **kwargs):
 | 
	
		
			
				|  |  | +        qs = self.get_object()
 | 
	
		
			
				|  |  | +        data = self.request.data
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        location_code = data.get('location_code')
 | 
	
		
			
				|  |  | +        # 处理库位对象
 | 
	
		
			
				|  |  | +        location_obj = LocationModel.objects.filter(location_code=location_code).first()
 | 
	
		
			
				|  |  | +        if not location_obj:
 | 
	
		
			
				|  |  | +            logger.info(f"库位 {location_code} 不存在")
 | 
	
		
			
				|  |  | +            return Response(
 | 
	
		
			
				|  |  | +                {'code': '400', 'message': '库位不存在', 'data': None},
 | 
	
		
			
				|  |  | +                status=status.HTTP_400_BAD_REQUEST
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            data['id'] = location_obj.id
 | 
	
		
			
				|  |  | +            logger.info(f"库位 {location_code} 已存在")
 | 
	
		
			
				|  |  | +            serializer = self.get_serializer(qs, data=data)
 | 
	
		
			
				|  |  | +            serializer.is_valid(raise_exception=True)
 | 
	
		
			
				|  |  | +            serializer.save()
 | 
	
		
			
				|  |  | +            headers = self.get_success_headers(serializer.data)
 | 
	
		
			
				|  |  | +            self.handle_group_location_status(location_code,location_obj.location_group)
 | 
	
		
			
				|  |  | +            return Response(serializer.data, status=200, headers=headers)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def handle_group_location_status(self,location_code,location_group):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        处理库位组和库位的关联关系
 | 
	
		
			
				|  |  | +        :param location_code: 库位编码
 | 
	
		
			
				|  |  | +        :param location_group: 库位组编码
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        # 1. 获取库位空闲状态的库位数目
 | 
	
		
			
				|  |  | +        location_obj_number = LocationModel.objects.filter(
 | 
	
		
			
				|  |  | +            location_group=location_group,
 | 
	
		
			
				|  |  | +            status='available'
 | 
	
		
			
				|  |  | +        ).all().count()
 | 
	
		
			
				|  |  | +        # 2. 获取库位组对象
 | 
	
		
			
				|  |  | +        logger.info(f"库位组 {location_group} 下的库位数目:{location_obj_number}")
 | 
	
		
			
				|  |  | +        # 1. 获取库位和库位组的关联关系
 | 
	
		
			
				|  |  | +        location_group_obj = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | +            group_code=location_group
 | 
	
		
			
				|  |  | +        ).first()
 | 
	
		
			
				|  |  | +        if not location_group_obj:
 | 
	
		
			
				|  |  | +            logger.info(f"库位组 {location_group} 不存在")
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            if location_obj_number == 0:
 | 
	
		
			
				|  |  | +                # 库位组库位已满,更新库位组状态为full
 | 
	
		
			
				|  |  | +                location_group_obj.status = 'full'
 | 
	
		
			
				|  |  | +                location_group_obj.save()
 | 
	
		
			
				|  |  | +            elif location_obj_number < location_group_obj.max_capacity:
 | 
	
		
			
				|  |  | +                location_group_obj.status = 'occupied'
 | 
	
		
			
				|  |  | +                location_group_obj.save()
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                location_group_obj.status = 'available'
 | 
	
		
			
				|  |  | +                location_group_obj.save()
 | 
	
		
			
				|  |  | +       
 | 
	
		
			
				|  |  | +class locationGroupViewSet(viewsets.ModelViewSet):
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +        retrieve:
 | 
	
		
			
				|  |  | +            Response a data list(get)
 | 
	
		
			
				|  |  | +            list:
 | 
	
		
			
				|  |  | +            Response a data list(all)
 | 
	
		
			
				|  |  | +        create:
 | 
	
		
			
				|  |  | +            Create a data line(post)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        delete:
 | 
	
		
			
				|  |  | +            Delete a data line(delete)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    """
 | 
	
		
			
				|  |  | +    # authentication_classes = []  # 禁用所有认证类
 | 
	
		
			
				|  |  | +    # permission_classes = [AllowAny]  # 允许任意访问
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    pagination_class = MyPageNumberPagination   
 | 
	
		
			
				|  |  | +    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
 | 
	
		
			
				|  |  | +    ordering_fields = ['id', "create_time", "update_time", ]
 | 
	
		
			
				|  |  | +    filter_class = LocationGroupFilter
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def get_project(self):
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            id = self.kwargs.get('pk')
 | 
	
		
			
				|  |  | +            return id
 | 
	
		
			
				|  |  | +        except:
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                           
 | 
	
		
			
				|  |  | +    def get_queryset(self):             
 | 
	
		
			
				|  |  | +        id = self.get_project()
 | 
	
		
			
				|  |  | +        if self.request.user:
 | 
	
		
			
				|  |  | +            if id is None:
 | 
	
		
			
				|  |  | +                return LocationGroupModel.objects.filter()  
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                return LocationGroupModel.objects.filter(id=id)            
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            return LocationGroupModel.objects.none()                           
 | 
	
		
			
				|  |  | +    def get_serializer_class(self):                                             
 | 
	
		
			
				|  |  | +        if self.action == 'list':
 | 
	
		
			
				|  |  | +            return LocationGroupListSerializer          
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        elif self.action == 'update':
 | 
	
		
			
				|  |  | +            return LocationGroupPostSerializer
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        elif self.action =='retrieve':
 | 
	
		
			
				|  |  | +            return LocationGroupListSerializer      
 | 
	
		
			
				|  |  | +    
 | 
	
		
			
				|  |  | +    def update(self, request, *args, **kwargs):
 | 
	
		
			
				|  |  | +        data = self.request.data
 | 
	
		
			
				|  |  | +        order_month = str(timezone.now().strftime('%Y%m'))
 | 
	
		
			
				|  |  | +        data['month'] = order_month
 | 
	
		
			
				|  |  | +        group_code = data.get('group_code')
 | 
	
		
			
				|  |  | +        # 处理库位组对象
 | 
	
		
			
				|  |  | +        group_obj = LocationGroupModel.objects.filter(group_code=group_code).first()
 | 
	
		
			
				|  |  | +        if group_obj:
 | 
	
		
			
				|  |  | +            data['id'] = group_obj.id
 | 
	
		
			
				|  |  | +            logger.info(f"库位组 {group_code} 已存在")
 | 
	
		
			
				|  |  | +        else:
 | 
	
		
			
				|  |  | +            logger.info(f"库位组 {group_code} 不存在,创建库位组对象")
 | 
	
		
			
				|  |  | +            serializer_list = LocationGroupPostSerializer(data=data)
 | 
	
		
			
				|  |  | +            serializer_list.is_valid(raise_exception=True)
 | 
	
		
			
				|  |  | +            serializer_list.save()
 | 
	
		
			
				|  |  | +            data['id'] = serializer_list.data.get('id')
 | 
	
		
			
				|  |  | +        return Response(data, status=status.HTTP_201_CREATED)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  class LocationAllocation:
 | 
	
		
			
				|  |  |      # 入库规则函数
 | 
	
		
			
				|  |  |      # fun:get_pallet_count_by_batch: 根据托盘码查询批次下托盘总数
 | 
	
		
			
				|  |  | +    # fun:get_left_locationGroup_number_by_type: 获取每层库位组剩余数量
 | 
	
		
			
				|  |  |      # fun:get_location_type: 根据托盘数目获取库位类型
 | 
	
		
			
				|  |  | -    # fun:updata_location_container_link: 更新库位和托盘的关联关系
 | 
	
		
			
				|  |  | +    # fun:update_location_container_link: 更新库位和托盘的关联关系
 | 
	
		
			
				|  |  | +    # fun:update_location_group_batch: 更新库位组的批次
 | 
	
		
			
				|  |  | +    # fun:update_batch_status: 更新批次状态yes/no
 | 
	
		
			
				|  |  | +    # fun:update_location_status: 更新库位状态和
 | 
	
		
			
				|  |  | +    # fun:up
 | 
	
		
			
				|  |  |      # fun:get_batch_status: 获取批次状态
 | 
	
		
			
				|  |  |      # fun:get_batch: 获取批次
 | 
	
		
			
				|  |  |      # fun:get_location_list_remainder: 获取可用库位的c_number列表
 | 
	
		
			
				|  |  | -    # fun:get_min_list_index: 获取最小的库位
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      # fun:get_location_by_type_remainder: 根据库位类型获取库位
 | 
	
		
			
				|  |  |      # fun:get_location_by_type: 第一次入库,根据库位类型获取库位
 | 
	
		
			
				|  |  |      # fun:get_location_by_status: 根据库位状态获取库位
 | 
	
	
		
			
				|  | @@ -66,29 +240,110 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  |          else:
 | 
	
		
			
				|  |  |              print (f"容器 {container_code} 已组盘")
 | 
	
		
			
				|  |  | -        batch_container_count = ContainerDetailModel.objects.filter(
 | 
	
		
			
				|  |  | +        batch_container = ContainerDetailModel.objects.filter(
 | 
	
		
			
				|  |  |               batch = container_detail.batch.id,
 | 
	
		
			
				|  |  |               status = 1
 | 
	
		
			
				|  |  | -        ).count()
 | 
	
		
			
				|  |  | -       
 | 
	
		
			
				|  |  | +        ).all()
 | 
	
		
			
				|  |  | +        # 统计批次下的不同托盘 item.contianer_id
 | 
	
		
			
				|  |  | +        batch_container_count = 0
 | 
	
		
			
				|  |  | +        container_ids = []
 | 
	
		
			
				|  |  | +        for item in batch_container:
 | 
	
		
			
				|  |  | +            if item.container_id not in container_ids: 
 | 
	
		
			
				|  |  | +                batch_container_count = batch_container_count + 1
 | 
	
		
			
				|  |  | +                container_ids.append(item.container_id)
 | 
	
		
			
				|  |  | +        batch_item = BoundBatchModel.objects.filter(  bound_number = container_detail.batch.bound_number).first()
 | 
	
		
			
				|  |  | +        if not batch_item:
 | 
	
		
			
				|  |  | +            print(f"批次号获取失败!")
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +        batch_item.container_number = batch_container_count
 | 
	
		
			
				|  |  | +        batch_item.save()
 | 
	
		
			
				|  |  |          return batch_container_count
 | 
	
		
			
				|  |  |      
 | 
	
		
			
				|  |  | -    def get_location_type(self,container_count):
 | 
	
		
			
				|  |  | -        """
 | 
	
		
			
				|  |  | -        根据托盘数目获取库位类型
 | 
	
		
			
				|  |  | -        :param container_count: 托盘数目
 | 
	
		
			
				|  |  | -        :return: 库位类型
 | 
	
		
			
				|  |  | -        """
 | 
	
		
			
				|  |  | -        if container_count <= 1:
 | 
	
		
			
				|  |  | -            return ["T1"]
 | 
	
		
			
				|  |  | -        elif container_count <= 2:
 | 
	
		
			
				|  |  | -            return ["T2"]
 | 
	
		
			
				|  |  | -        elif container_count <= 4:
 | 
	
		
			
				|  |  | -            return ["S4","T4"]
 | 
	
		
			
				|  |  | +    def get_left_locationGroup_number_by_type(self):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        获取每层库位组剩余数量
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            # 定义库位组和层号
 | 
	
		
			
				|  |  | +            group = ['T1', 'T2', 'S4', 'T4', 'T5']
 | 
	
		
			
				|  |  | +            layer = [1, 2, 3]
 | 
	
		
			
				|  |  | +            # 初始化结果列表,包含三个空字典对应三个层
 | 
	
		
			
				|  |  | +            left_number = [{} for _ in layer]
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            for item in group:
 | 
	
		
			
				|  |  | +                for idx, layer_num in enumerate(layer):
 | 
	
		
			
				|  |  | +                    # 检查库位组是否存在(不考虑状态)
 | 
	
		
			
				|  |  | +                    exists = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | +                        group_type=item,
 | 
	
		
			
				|  |  | +                        layer=layer_num
 | 
	
		
			
				|  |  | +                    ).exists()
 | 
	
		
			
				|  |  | +                    
 | 
	
		
			
				|  |  | +                    if not exists:
 | 
	
		
			
				|  |  | +                        print(f"库位组 {item}_{layer_num} 不存在")
 | 
	
		
			
				|  |  | +                        left_number[idx][item] = 0
 | 
	
		
			
				|  |  | +                    else:
 | 
	
		
			
				|  |  | +                        # 统计可用状态的库位组数量
 | 
	
		
			
				|  |  | +                        count = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | +                            group_type=item,
 | 
	
		
			
				|  |  | +                            layer=layer_num,
 | 
	
		
			
				|  |  | +                            status='available'
 | 
	
		
			
				|  |  | +                        ).count()
 | 
	
		
			
				|  |  | +                        left_number[idx][item] = count
 | 
	
		
			
				|  |  | +                        
 | 
	
		
			
				|  |  | +            return left_number
 | 
	
		
			
				|  |  | +        except Exception as e:
 | 
	
		
			
				|  |  | +            logger.error(f"获取库位组剩余数量失败:{str(e)}")
 | 
	
		
			
				|  |  | +            print(f"获取库位组剩余数量失败:{str(e)}")
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    def get_location_type(self,container_code):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        :param container_code: 托盘码
 | 
	
		
			
				|  |  | +        :return: 库位类型列表
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        batch = self.get_batch(container_code)
 | 
	
		
			
				|  |  | +        if not batch:
 | 
	
		
			
				|  |  | +            print(f"类型分配中批次号获取失败!")
 | 
	
		
			
				|  |  | +            return None
 | 
	
		
			
				|  |  | +        location_solution = alloction_pre.objects.filter(batch_number=batch).first()
 | 
	
		
			
				|  |  | +        if not location_solution:
 | 
	
		
			
				|  |  | +            # 1. 获取托盘码对应批次号下所有的托盘数目
 | 
	
		
			
				|  |  | +            container_number = self.get_pallet_count_by_batch(container_code)
 | 
	
		
			
				|  |  | +            print (f"该批次下托盘总数:{container_number}")
 | 
	
		
			
				|  |  | +            # 2. 计算每层剩余的库位数目
 | 
	
		
			
				|  |  | +            layer_number=self.get_pallet_count_by_batch()
 | 
	
		
			
				|  |  | +            # 3. 查看最新库位分配方案
 | 
	
		
			
				|  |  | +            location_solution_last = alloction_pre.objects.filter().order_by('-id').first()
 | 
	
		
			
				|  |  | +            if not location_solution_last:
 | 
	
		
			
				|  |  | +                layer1_pressure =0
 | 
	
		
			
				|  |  | +                layer2_pressure =0
 | 
	
		
			
				|  |  | +                layer3_pressure =0
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                layer1_pressure = location_solution_last.layer1_pressure
 | 
	
		
			
				|  |  | +                layer2_pressure = location_solution_last.layer2_pressure
 | 
	
		
			
				|  |  | +                layer3_pressure = location_solution_last.layer3_pressure
 | 
	
		
			
				|  |  | +            # 4. 根据工作压力和库位类型,使用贪心算法,(AGV只有两个库位,故只给考虑1 2 层工作压力,第三层仅作为1,2层的补充,不考虑压力)获取库位类型列表,完成任务之后更新压力/TODO:需要考虑库位类型和库位数量的关系
 | 
	
		
			
				|  |  | +            if layer1_pressure <=layer2_pressure:
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            print(f"库位类型:{location_type}")
 | 
	
		
			
				|  |  | +            # 5. 保存库位分配方案
 | 
	
		
			
				|  |  | +            alloction_pre.objects.create(
 | 
	
		
			
				|  |  | +                batch_number=batch,
 | 
	
		
			
				|  |  | +                layer1_pressure=layer1_pressure,
 | 
	
		
			
				|  |  | +                layer2_pressure=layer2_pressure,
 | 
	
		
			
				|  |  | +                layer3_pressure=layer3_pressure,
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                location_type=','.join(location_type)
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  | +            return location_type
 | 
	
		
			
				|  |  |          else:
 | 
	
		
			
				|  |  | -            return ["T5"]
 | 
	
		
			
				|  |  | +            print(f"库位类型:{location_solution.location_type}")
 | 
	
		
			
				|  |  | +            return location_solution.location_type.split(",")
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  |      @transaction.atomic
 | 
	
		
			
				|  |  | -    def updata_location_container_link(self,location_code,container_code):
 | 
	
		
			
				|  |  | +    def update_location_container_link(self,location_code,container_code):
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          更新库位和托盘的关联关系
 | 
	
		
			
				|  |  |          :param location_code: 库位编码
 | 
	
	
		
			
				|  | @@ -111,6 +366,7 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |                  )
 | 
	
		
			
				|  |  |                  location_container_link.save()
 | 
	
		
			
				|  |  |                  print(f"更新库位和托盘的关联关系成功!")
 | 
	
		
			
				|  |  | +                return True
 | 
	
		
			
				|  |  |              # 3. 更新库位和托盘的关联关系
 | 
	
		
			
				|  |  |              else:
 | 
	
		
			
				|  |  |                  LocationContainerLink.objects.filter(location=location).update(location=location, container=container)
 | 
	
	
		
			
				|  | @@ -120,6 +376,142 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |              logger.error(f"更新库位和托盘的关联关系失败:{str(e)}")
 | 
	
		
			
				|  |  |              print(f"更新库位和托盘的关联关系失败:{str(e)}")
 | 
	
		
			
				|  |  |              return False    
 | 
	
		
			
				|  |  | +    def update_location_group_batch(self,location,container_code):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        :param location: 库位对象
 | 
	
		
			
				|  |  | +        :param container_code: 托盘码
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            # 1. 获取库位组
 | 
	
		
			
				|  |  | +            location_group = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | +                group_code=location.location_group
 | 
	
		
			
				|  |  | +            ).first()
 | 
	
		
			
				|  |  | +            if not location_group:
 | 
	
		
			
				|  |  | +                print(f"库位组获取失败!")
 | 
	
		
			
				|  |  | +                return False
 | 
	
		
			
				|  |  | +            # 2. 更新库位组的批次
 | 
	
		
			
				|  |  | +            bound_number=self.get_batch(container_code)
 | 
	
		
			
				|  |  | +            if not bound_number:
 | 
	
		
			
				|  |  | +                print(f"批次号获取失败!")
 | 
	
		
			
				|  |  | +                return False
 | 
	
		
			
				|  |  | +            location_group.current_batch = bound_number
 | 
	
		
			
				|  |  | +            location_group.save()
 | 
	
		
			
				|  |  | +            print(f"更新库位组的批次成功!")
 | 
	
		
			
				|  |  | +            return True
 | 
	
		
			
				|  |  | +        except Exception as e:       
 | 
	
		
			
				|  |  | +            logger.error(f"更新库位组的批次失败:{str(e)}")
 | 
	
		
			
				|  |  | +            print(f"更新库位组的批次失败:{str(e)}")
 | 
	
		
			
				|  |  | +            return False    
 | 
	
		
			
				|  |  | +    def update_location_status(self,location_code,status):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        更新库位状态
 | 
	
		
			
				|  |  | +        :param location_code: 库位编码
 | 
	
		
			
				|  |  | +        :param status: 库位状态
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            # 1. 获取库位
 | 
	
		
			
				|  |  | +            location = LocationModel.objects.filter(
 | 
	
		
			
				|  |  | +                location_code=location_code
 | 
	
		
			
				|  |  | +            ).first()
 | 
	
		
			
				|  |  | +            if not location:
 | 
	
		
			
				|  |  | +                print(f"库位获取失败!")
 | 
	
		
			
				|  |  | +                return False
 | 
	
		
			
				|  |  | +            # 2. 更新库位状态
 | 
	
		
			
				|  |  | +            location.status = status
 | 
	
		
			
				|  |  | +            location.save()
 | 
	
		
			
				|  |  | +            print(f"更新库位状态成功!")
 | 
	
		
			
				|  |  | +            return True
 | 
	
		
			
				|  |  | +        except Exception as e:       
 | 
	
		
			
				|  |  | +            logger.error(f"更新库位状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            print(f"更新库位状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            return False    
 | 
	
		
			
				|  |  | +    def update_location_group_status(self, location_code):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        更新库位组状态
 | 
	
		
			
				|  |  | +        :param location_code: 库位编码
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            # 1. 获取库位
 | 
	
		
			
				|  |  | +            location = LocationModel.objects.filter(
 | 
	
		
			
				|  |  | +                location_code=location_code
 | 
	
		
			
				|  |  | +            ).first()
 | 
	
		
			
				|  |  | +            if not location:
 | 
	
		
			
				|  |  | +                print(f"库位获取失败!")
 | 
	
		
			
				|  |  | +                return False
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            # 2. 获取库位组
 | 
	
		
			
				|  |  | +            location_group = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | +                group_code=location.location_group
 | 
	
		
			
				|  |  | +            ).first()
 | 
	
		
			
				|  |  | +            if not location_group:
 | 
	
		
			
				|  |  | +                print(f"库位组获取失败!")
 | 
	
		
			
				|  |  | +                return False
 | 
	
		
			
				|  |  | +            current=0
 | 
	
		
			
				|  |  | +            for location_item in location_group.location_items.all():
 | 
	
		
			
				|  |  | +                if location_item.status != 'available':
 | 
	
		
			
				|  |  | +                    current=current + 1
 | 
	
		
			
				|  |  | +            # 3. 更新库位组状态
 | 
	
		
			
				|  |  | +            if current == 0:
 | 
	
		
			
				|  |  | +                location_group.status = 'available'
 | 
	
		
			
				|  |  | +            elif current == location_group.max_capacity:
 | 
	
		
			
				|  |  | +                location_group.status = 'full'
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                location_group.status = 'occupied'
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +            location_group.current_goods_quantity = sum(
 | 
	
		
			
				|  |  | +                    [loc.current_quantity for loc in location_group.location_items.all()]
 | 
	
		
			
				|  |  | +                )
 | 
	
		
			
				|  |  | +            location_group.current_quantity = current
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +            location_group.save()
 | 
	
		
			
				|  |  | +            print(f"更新库位组状态成功!")
 | 
	
		
			
				|  |  | +            return True
 | 
	
		
			
				|  |  | +        except Exception as e:       
 | 
	
		
			
				|  |  | +            logger.error(f"更新库位组状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            print(f"更新库位组状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +    def update_batch_status(self,container_code,status):
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        更新批次状态
 | 
	
		
			
				|  |  | +        :param batch_id: 批次id
 | 
	
		
			
				|  |  | +        :param status: 批次状态
 | 
	
		
			
				|  |  | +        :return:
 | 
	
		
			
				|  |  | +        """
 | 
	
		
			
				|  |  | +        try:
 | 
	
		
			
				|  |  | +            # 1. 通过托盘码获取容器详情
 | 
	
		
			
				|  |  | +            container = ContainerListModel.objects.filter(
 | 
	
		
			
				|  |  | +                container_code=container_code
 | 
	
		
			
				|  |  | +            ).first()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if not container:
 | 
	
		
			
				|  |  | +                logger.error(f"托盘 {container_code} 不存在")
 | 
	
		
			
				|  |  | +                print(f"托盘 {container_code} 不存在")
 | 
	
		
			
				|  |  | +                return None
 | 
	
		
			
				|  |  | +            # 2. 获取关联的批次明细
 | 
	
		
			
				|  |  | +            container_detail = ContainerDetailModel.objects.filter(
 | 
	
		
			
				|  |  | +                container=container.id,
 | 
	
		
			
				|  |  | +                status=1
 | 
	
		
			
				|  |  | +            ).first()
 | 
	
		
			
				|  |  | +            if not container_detail:
 | 
	
		
			
				|  |  | +                print (f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +                logger.error(f"容器 {container_code} 未组盘")
 | 
	
		
			
				|  |  | +                return None
 | 
	
		
			
				|  |  | +            else:
 | 
	
		
			
				|  |  | +                print (f"容器 {container_code} 已组盘")
 | 
	
		
			
				|  |  | +            # 3. 更新批次状态
 | 
	
		
			
				|  |  | +            batch = container_detail.batch
 | 
	
		
			
				|  |  | +            batch.status = status
 | 
	
		
			
				|  |  | +            batch.save()
 | 
	
		
			
				|  |  | +            print(f"更新批次状态成功!")
 | 
	
		
			
				|  |  | +            return True
 | 
	
		
			
				|  |  | +        except Exception as e:       
 | 
	
		
			
				|  |  | +            logger.error(f"更新批次状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            print(f"更新批次状态失败:{str(e)}")
 | 
	
		
			
				|  |  | +            return False  
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      def get_batch_status(self,container_code):
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          获取批次状态
 | 
	
	
		
			
				|  | @@ -185,28 +577,19 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  |          if not location_list:
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  | +        min_c_number=1000
 | 
	
		
			
				|  |  | +        min_c_number_index=1000
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        available_c_numbers = [
 | 
	
		
			
				|  |  | -            loc.c_number for loc in location_list 
 | 
	
		
			
				|  |  | -            if loc.status == 'available'
 | 
	
		
			
				|  |  | -        ]
 | 
	
		
			
				|  |  | -        
 | 
	
		
			
				|  |  | -        return available_c_numbers if available_c_numbers else None
 | 
	
		
			
				|  |  | -    def get_min_list_index(self,list):
 | 
	
		
			
				|  |  | -        """
 | 
	
		
			
				|  |  | -        获取最小的库位
 | 
	
		
			
				|  |  | -        :param list: 库位列表
 | 
	
		
			
				|  |  | -        :return: 最小库位
 | 
	
		
			
				|  |  | -        """
 | 
	
		
			
				|  |  | -        if not list:
 | 
	
		
			
				|  |  | +        for location in location_list:
 | 
	
		
			
				|  |  | +            if location.status != 'available':
 | 
	
		
			
				|  |  | +                continue
 | 
	
		
			
				|  |  | +            if int(location.c_number)<min_c_number:
 | 
	
		
			
				|  |  | +                min_c_number=int(location.c_number)
 | 
	
		
			
				|  |  | +                min_c_number_index=location_list.index(location)
 | 
	
		
			
				|  |  | +        if min_c_number_index==1000:
 | 
	
		
			
				|  |  |              return None
 | 
	
		
			
				|  |  | -        min_index = 0
 | 
	
		
			
				|  |  | -        for i in range(len(list)):
 | 
	
		
			
				|  |  | -            if list[i] < list[min_index]:
 | 
	
		
			
				|  |  | -                min_index = i
 | 
	
		
			
				|  |  | -        return min_index
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +        else:  
 | 
	
		
			
				|  |  | +            return min_c_number_index
 | 
	
		
			
				|  |  |      @transaction.atomic
 | 
	
		
			
				|  |  |      def get_location_by_type_remainder(self, batch, layer):
 | 
	
		
			
				|  |  |          """
 | 
	
	
		
			
				|  | @@ -252,11 +635,8 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          else:
 | 
	
		
			
				|  |  |              ordered_groups = location_groups.none()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        # 合并所有库位组中的库位
 | 
	
		
			
				|  |  |          locations = []
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  |          locations.extend(ordered_groups.first().location_items.all())  # 假设location_items是关联字段
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |          return locations if locations else None
 | 
	
		
			
				|  |  |      @transaction.atomic
 | 
	
		
			
				|  |  |      def get_location_by_status(self,container_code,start_location,layer):
 | 
	
	
		
			
				|  | @@ -273,199 +653,78 @@ class LocationAllocation:
 | 
	
		
			
				|  |  |          if status == 1:
 | 
	
		
			
				|  |  |              # 2. 获取库位组
 | 
	
		
			
				|  |  |              print (f"第一次入库")
 | 
	
		
			
				|  |  | -            container_number = self.get_pallet_count_by_batch(container_code)
 | 
	
		
			
				|  |  | -            print (f"该批次下托盘总数:{container_number}")
 | 
	
		
			
				|  |  | -            location_type_list = self.get_location_type(container_number)
 | 
	
		
			
				|  |  | +           
 | 
	
		
			
				|  |  | +            location_type_list = self.get_location_type(container_code)
 | 
	
		
			
				|  |  |              print(f"库位类型:{location_type_list}")
 | 
	
		
			
				|  |  |              location_list = self.get_location_by_type(location_type_list,start_location,layer)
 | 
	
		
			
				|  |  |              print(f"库位列表:{location_list}")
 | 
	
		
			
				|  |  | -            location_list_remainder = self.get_location_list_remainder(location_list)
 | 
	
		
			
				|  |  | -            print(f"库位列表剩余:{location_list_remainder}")
 | 
	
		
			
				|  |  | -            if not location_list_remainder:
 | 
	
		
			
				|  |  | +            location_min_index = self.get_location_list_remainder(location_list)
 | 
	
		
			
				|  |  | +            print(f"库位安排到第{location_min_index+1}个库位:{location_list[location_min_index]}")
 | 
	
		
			
				|  |  | +            if not location_list[location_min_index]:
 | 
	
		
			
				|  |  |                  # 库位已满,返回None
 | 
	
		
			
				|  |  |                  return None
 | 
	
		
			
				|  |  |              else:
 | 
	
		
			
				|  |  | -                location_index = self.get_min_list_index(location_list_remainder)
 | 
	
		
			
				|  |  | -                # 返回和托盘关联的库位、库位剩余、库位类型
 | 
	
		
			
				|  |  | -                return location_list[location_index]
 | 
	
		
			
				|  |  | +                
 | 
	
		
			
				|  |  | +                return location_list[location_min_index]
 | 
	
		
			
				|  |  |          elif status == 2:
 | 
	
		
			
				|  |  |              print(f"部分入库")
 | 
	
		
			
				|  |  |              # 2. 获取库位组
 | 
	
		
			
				|  |  |              location_list = self.get_location_by_type_remainder(self.get_batch(container_code),layer)
 | 
	
		
			
				|  |  | -            location_list_remainder = self.get_location_list_remainder(location_list)
 | 
	
		
			
				|  |  | -            if not location_list_remainder:
 | 
	
		
			
				|  |  | +            print(f"库位列表:{location_list}")
 | 
	
		
			
				|  |  | +            location_min_index = self.get_location_list_remainder(location_list)
 | 
	
		
			
				|  |  | +            print(f"库位安排到第{location_min_index+1}个库位:{location_list[location_min_index]}")
 | 
	
		
			
				|  |  | +            if not location_list[location_min_index]:
 | 
	
		
			
				|  |  |                  # 库位已满,返回None
 | 
	
		
			
				|  |  |                  return None
 | 
	
		
			
				|  |  |              else:
 | 
	
		
			
				|  |  | -                location_index = self.get_min_list_index(location_list_remainder)
 | 
	
		
			
				|  |  | -                # 返回和托盘关联的库位、库位剩余、库位类型
 | 
	
		
			
				|  |  | -                return location_list[location_index]
 | 
	
		
			
				|  |  | -         
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -class locationViewSet(viewsets.ModelViewSet):
 | 
	
		
			
				|  |  | -    """
 | 
	
		
			
				|  |  | -        retrieve:
 | 
	
		
			
				|  |  | -            Response a data list(get)
 | 
	
		
			
				|  |  | -            list:
 | 
	
		
			
				|  |  | -            Response a data list(all)
 | 
	
		
			
				|  |  | -        create:
 | 
	
		
			
				|  |  | -            Create a data line(post)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        delete:
 | 
	
		
			
				|  |  | -            Delete a data line(delete)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    """
 | 
	
		
			
				|  |  | -    # authentication_classes = []  # 禁用所有认证类
 | 
	
		
			
				|  |  | -    # permission_classes = [AllowAny]  # 允许任意访问
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    pagination_class = MyPageNumberPagination   
 | 
	
		
			
				|  |  | -    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
 | 
	
		
			
				|  |  | -    ordering_fields = ['id', "create_time", "update_time", ]
 | 
	
		
			
				|  |  | -    filter_class = LocationFilter
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    def get_project(self):
 | 
	
		
			
				|  |  | -        try:
 | 
	
		
			
				|  |  | -            id = self.kwargs.get('pk')
 | 
	
		
			
				|  |  | -            return id
 | 
	
		
			
				|  |  | -        except:
 | 
	
		
			
				|  |  | -            return None
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    def get_queryset(self):
 | 
	
		
			
				|  |  | -        id = self.get_project()
 | 
	
		
			
				|  |  | -        if self.request.user:
 | 
	
		
			
				|  |  | -            if id is None:
 | 
	
		
			
				|  |  | -                return LocationModel.objects.filter()
 | 
	
		
			
				|  |  | -            else:
 | 
	
		
			
				|  |  | -                return LocationModel.objects.filter( id=id)
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            return LocationModel.objects.none()
 | 
	
		
			
				|  |  | -    def get_serializer_class(self):
 | 
	
		
			
				|  |  | -        if self.action == 'list':
 | 
	
		
			
				|  |  | -            return LocationListSerializer
 | 
	
		
			
				|  |  | -        elif self.action == 'update':
 | 
	
		
			
				|  |  | -            return LocationPostSerializer
 | 
	
		
			
				|  |  | -        elif self.action =='retrieve':
 | 
	
		
			
				|  |  | -            return LocationListSerializer
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    def update(self, request, *args, **kwargs):
 | 
	
		
			
				|  |  | -        qs = self.get_object()
 | 
	
		
			
				|  |  | -        data = self.request.data
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        location_code = data.get('location_code')
 | 
	
		
			
				|  |  | -        # 处理库位对象
 | 
	
		
			
				|  |  | -        location_obj = LocationModel.objects.filter(location_code=location_code).first()
 | 
	
		
			
				|  |  | -        if not location_obj:
 | 
	
		
			
				|  |  | -            logger.info(f"库位 {location_code} 不存在")
 | 
	
		
			
				|  |  | -            return Response(
 | 
	
		
			
				|  |  | -                {'code': '400', 'message': '库位不存在', 'data': None},
 | 
	
		
			
				|  |  | -                status=status.HTTP_400_BAD_REQUEST
 | 
	
		
			
				|  |  | -            )
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            data['id'] = location_obj.id
 | 
	
		
			
				|  |  | -            logger.info(f"库位 {location_code} 已存在")
 | 
	
		
			
				|  |  | -            serializer = self.get_serializer(qs, data=data)
 | 
	
		
			
				|  |  | -            serializer.is_valid(raise_exception=True)
 | 
	
		
			
				|  |  | -            serializer.save()
 | 
	
		
			
				|  |  | -            headers = self.get_success_headers(serializer.data)
 | 
	
		
			
				|  |  | -            self.handle_group_location_status(location_code,location_obj.location_group)
 | 
	
		
			
				|  |  | -            return Response(serializer.data, status=200, headers=headers)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    def handle_group_location_status(self,location_code,location_group):
 | 
	
		
			
				|  |  | +                return location_list[location_min_index]
 | 
	
		
			
				|  |  | +        elif status == 3:
 | 
	
		
			
				|  |  | +            print(f"全部入库")
 | 
	
		
			
				|  |  | +            # 2. 获取库位组
 | 
	
		
			
				|  |  | +            location_list = self.get_location_by_type_remainder(self.get_batch(container_code),layer)
 | 
	
		
			
				|  |  | +            return location_list
 | 
	
		
			
				|  |  | +            
 | 
	
		
			
				|  |  | +  
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  | -        处理库位组和库位的关联关系
 | 
	
		
			
				|  |  | -        :param location_code: 库位编码
 | 
	
		
			
				|  |  | -        :param location_group: 库位组编码
 | 
	
		
			
				|  |  | -        :return:
 | 
	
		
			
				|  |  | +        根据库位状态清除库位
 | 
	
		
			
				|  |  | +        :param container_code: 托盘码
 | 
	
		
			
				|  |  | +        :param start_location: 起始库位 if in1 优先考虑left_priority, if in2 优先考虑right_priority 就是获取库位组列表之后进行排序
 | 
	
		
			
				|  |  | +        :param layer: 层数 限定层数
 | 
	
		
			
				|  |  | +        :return: 库位列表
 | 
	
		
			
				|  |  |          """
 | 
	
		
			
				|  |  | -        # 1. 获取库位空闲状态的库位数目
 | 
	
		
			
				|  |  | -        location_obj_number = LocationModel.objects.filter(
 | 
	
		
			
				|  |  | -            location_group=location_group,
 | 
	
		
			
				|  |  | -            status='available'
 | 
	
		
			
				|  |  | -        ).all().count()
 | 
	
		
			
				|  |  | -        # 2. 获取库位组对象
 | 
	
		
			
				|  |  | -        logger.info(f"库位组 {location_group} 下的库位数目:{location_obj_number}")
 | 
	
		
			
				|  |  | -        # 1. 获取库位和库位组的关联关系
 | 
	
		
			
				|  |  | -        location_group_obj = LocationGroupModel.objects.filter(
 | 
	
		
			
				|  |  | -            group_code=location_group
 | 
	
		
			
				|  |  | -        ).first()
 | 
	
		
			
				|  |  | -        if not location_group_obj:
 | 
	
		
			
				|  |  | -            logger.info(f"库位组 {location_group} 不存在")
 | 
	
		
			
				|  |  | -            return None
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            if location_obj_number == 0:
 | 
	
		
			
				|  |  | -                # 库位组库位已满,更新库位组状态为full
 | 
	
		
			
				|  |  | -                location_group_obj.status = 'full'
 | 
	
		
			
				|  |  | -                location_group_obj.save()
 | 
	
		
			
				|  |  | -            elif location_obj_number < location_group_obj.max_capacity:
 | 
	
		
			
				|  |  | -                location_group_obj.status = 'occupied'
 | 
	
		
			
				|  |  | -                location_group_obj.save()
 | 
	
		
			
				|  |  | +        # 1. 获取批次状态 102 为已组盘 103 为部分入库 104 为全部入库
 | 
	
		
			
				|  |  | +        status = self.get_batch_status(container_code)
 | 
	
		
			
				|  |  | +        # 
 | 
	
		
			
				|  |  | +        if status == 1:
 | 
	
		
			
				|  |  | +            # 2. 获取库位组
 | 
	
		
			
				|  |  | +            print (f"第一次入库")
 | 
	
		
			
				|  |  | +            container_number = self.get_pallet_count_by_batch(container_code)
 | 
	
		
			
				|  |  | +            print (f"该批次下托盘总数:{container_number}")
 | 
	
		
			
				|  |  | +            location_type_list = self.get_location_type(container_number)
 | 
	
		
			
				|  |  | +            print(f"库位类型:{location_type_list}")
 | 
	
		
			
				|  |  | +            location_list = self.get_location_by_type(location_type_list,start_location,layer)
 | 
	
		
			
				|  |  | +            print(f"库位列表:{location_list}")
 | 
	
		
			
				|  |  | +            location_min_index = self.get_location_list_remainder(location_list)
 | 
	
		
			
				|  |  | +            print(f"库位安排到第{location_min_index+1}个库位:{location_list[location_min_index]}")
 | 
	
		
			
				|  |  | +            if not location_list[location_min_index]:
 | 
	
		
			
				|  |  | +                # 库位已满,返回None
 | 
	
		
			
				|  |  | +                return None
 | 
	
		
			
				|  |  |              else:
 | 
	
		
			
				|  |  | -                location_group_obj.status = 'available'
 | 
	
		
			
				|  |  | -                location_group_obj.save()
 | 
	
		
			
				|  |  | -       
 | 
	
		
			
				|  |  | -class locationGroupViewSet(viewsets.ModelViewSet):
 | 
	
		
			
				|  |  | -    """
 | 
	
		
			
				|  |  | -        retrieve:
 | 
	
		
			
				|  |  | -            Response a data list(get)
 | 
	
		
			
				|  |  | -            list:
 | 
	
		
			
				|  |  | -            Response a data list(all)
 | 
	
		
			
				|  |  | -        create:
 | 
	
		
			
				|  |  | -            Create a data line(post)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        delete:
 | 
	
		
			
				|  |  | -            Delete a data line(delete)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    """
 | 
	
		
			
				|  |  | -    # authentication_classes = []  # 禁用所有认证类
 | 
	
		
			
				|  |  | -    # permission_classes = [AllowAny]  # 允许任意访问
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    pagination_class = MyPageNumberPagination   
 | 
	
		
			
				|  |  | -    filter_backends = [DjangoFilterBackend, OrderingFilter, ]
 | 
	
		
			
				|  |  | -    ordering_fields = ['id', "create_time", "update_time", ]
 | 
	
		
			
				|  |  | -    filter_class = LocationGroupFilter
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    def get_project(self):
 | 
	
		
			
				|  |  | -        try:
 | 
	
		
			
				|  |  | -            id = self.kwargs.get('pk')
 | 
	
		
			
				|  |  | -            return id
 | 
	
		
			
				|  |  | -        except:
 | 
	
		
			
				|  |  | -            return None
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -                           
 | 
	
		
			
				|  |  | -    def get_queryset(self):             
 | 
	
		
			
				|  |  | -        id = self.get_project()
 | 
	
		
			
				|  |  | -        if self.request.user:
 | 
	
		
			
				|  |  | -            if id is None:
 | 
	
		
			
				|  |  | -                return LocationGroupModel.objects.filter()  
 | 
	
		
			
				|  |  | +                location_code = location_list[location_min_index].location_code
 | 
	
		
			
				|  |  | +                self.update_location_status(location_code,'occupied')
 | 
	
		
			
				|  |  | +                return location_list[location_min_index]
 | 
	
		
			
				|  |  | +        elif status == 2:
 | 
	
		
			
				|  |  | +            print(f"部分入库")
 | 
	
		
			
				|  |  | +            # 2. 获取库位组
 | 
	
		
			
				|  |  | +            location_list = self.get_location_by_type_remainder(self.get_batch(container_code),layer)
 | 
	
		
			
				|  |  | +            print(f"库位列表:{location_list}")
 | 
	
		
			
				|  |  | +            location_min_index = 1
 | 
	
		
			
				|  |  | +            print(f"库位安排到第{location_min_index+1}个库位:{location_list[location_min_index]}")
 | 
	
		
			
				|  |  | +            if not location_list[location_min_index]:
 | 
	
		
			
				|  |  | +                # 库位已满,返回None
 | 
	
		
			
				|  |  | +                return None
 | 
	
		
			
				|  |  |              else:
 | 
	
		
			
				|  |  | -                return LocationGroupModel.objects.filter(id=id)            
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            return LocationGroupModel.objects.none()                           
 | 
	
		
			
				|  |  | -    def get_serializer_class(self):                                             
 | 
	
		
			
				|  |  | -        if self.action == 'list':
 | 
	
		
			
				|  |  | -            return LocationGroupListSerializer          
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        elif self.action == 'update':
 | 
	
		
			
				|  |  | -            return LocationGroupPostSerializer
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        elif self.action =='retrieve':
 | 
	
		
			
				|  |  | -            return LocationGroupListSerializer      
 | 
	
		
			
				|  |  | -    
 | 
	
		
			
				|  |  | -    def update(self, request, *args, **kwargs):
 | 
	
		
			
				|  |  | -        data = self.request.data
 | 
	
		
			
				|  |  | -        order_month = str(timezone.now().strftime('%Y%m'))
 | 
	
		
			
				|  |  | -        data['month'] = order_month
 | 
	
		
			
				|  |  | -        group_code = data.get('group_code')
 | 
	
		
			
				|  |  | -        # 处理库位组对象
 | 
	
		
			
				|  |  | -        group_obj = LocationGroupModel.objects.filter(group_code=group_code).first()
 | 
	
		
			
				|  |  | -        if group_obj:
 | 
	
		
			
				|  |  | -            data['id'] = group_obj.id
 | 
	
		
			
				|  |  | -            logger.info(f"库位组 {group_code} 已存在")
 | 
	
		
			
				|  |  | -        else:
 | 
	
		
			
				|  |  | -            logger.info(f"库位组 {group_code} 不存在,创建库位组对象")
 | 
	
		
			
				|  |  | -            serializer_list = LocationGroupPostSerializer(data=data)
 | 
	
		
			
				|  |  | -            serializer_list.is_valid(raise_exception=True)
 | 
	
		
			
				|  |  | -            serializer_list.save()
 | 
	
		
			
				|  |  | -            data['id'] = serializer_list.data.get('id')
 | 
	
		
			
				|  |  | -        return Response(data, status=status.HTTP_201_CREATED)
 | 
	
		
			
				|  |  | +                location_code = location_list[location_min_index].location_code
 | 
	
		
			
				|  |  | +                self.update_location_status(location_code,'occupied')
 | 
	
		
			
				|  |  | +                return location_list[location_min_index]
 | 
	
		
			
				|  |  | +  
 |