|
@@ -237,7 +237,7 @@ class LocationAllocation:
|
|
|
status=1
|
|
|
).first()
|
|
|
if not container_detail:
|
|
|
- logger.error(f"容器 {container_code} 未组盘")
|
|
|
+ logger.error(f"托盘 {container_code} 未组盘")
|
|
|
return None
|
|
|
|
|
|
batch_container = ContainerDetailModel.objects.filter(
|
|
@@ -384,6 +384,37 @@ class LocationAllocation:
|
|
|
logger.error(f"更新库位状态失败:{str(e)}")
|
|
|
print(f"更新库位状态失败:{str(e)}")
|
|
|
return False
|
|
|
+
|
|
|
+ def update_group_status_reserved(self,location_group_list):
|
|
|
+ """
|
|
|
+ 更新库位组状态
|
|
|
+ :param location_group_list: 库位组对象列表
|
|
|
+ :return:
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ for location_group in location_group_list:
|
|
|
+ # 1. 获取库位组
|
|
|
+ if not location_group:
|
|
|
+ print(f"库位组获取失败!")
|
|
|
+ return False
|
|
|
+ # 2. 更新库位组状态
|
|
|
+ location_group_id = location_group.split('_')[1]
|
|
|
+ location_group_item = LocationGroupModel.objects.filter(
|
|
|
+ id=location_group_id
|
|
|
+ ).first()
|
|
|
+ if not location_group_item:
|
|
|
+ print(f"库位组 {location_group} 不存在")
|
|
|
+ return False
|
|
|
+ # 3. 更新库位组状态
|
|
|
+ location_group_item.status = 'reserved'
|
|
|
+ location_group_item.save()
|
|
|
+
|
|
|
+ return True
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"更新库位组状态失败:{str(e)}")
|
|
|
+ print(f"更新库位组状态失败:{str(e)}")
|
|
|
+ return False
|
|
|
+ @transaction.atomic
|
|
|
def update_location_group_status(self, location_code):
|
|
|
"""
|
|
|
更新库位组状态
|
|
@@ -452,11 +483,10 @@ class LocationAllocation:
|
|
|
status=1
|
|
|
).first()
|
|
|
if not container_detail:
|
|
|
- print (f"容器 {container_code} 未组盘")
|
|
|
- logger.error(f"容器 {container_code} 未组盘")
|
|
|
+ print (f"托盘 {container_code} 未组盘")
|
|
|
+ logger.error(f"托盘 {container_code} 未组盘")
|
|
|
return None
|
|
|
- else:
|
|
|
- print (f"容器 {container_code} 已组盘")
|
|
|
+
|
|
|
# 3. 更新批次状态
|
|
|
batch = container_detail.batch
|
|
|
batch.status = status
|
|
@@ -488,11 +518,10 @@ class LocationAllocation:
|
|
|
status=1
|
|
|
).first()
|
|
|
if not container_detail:
|
|
|
- print (f"容器 {container_code} 未组盘")
|
|
|
- logger.error(f"容器 {container_code} 未组盘")
|
|
|
+ print (f"托盘 {container_code} 未组盘")
|
|
|
+ logger.error(f"托盘 {container_code} 未组盘")
|
|
|
return None
|
|
|
- else:
|
|
|
- print (f"容器 {container_code} 已组盘")
|
|
|
+
|
|
|
batch_status = container_detail.batch.status
|
|
|
return batch_status
|
|
|
def get_batch(self,container_code):
|
|
@@ -516,11 +545,10 @@ class LocationAllocation:
|
|
|
status=1
|
|
|
).first()
|
|
|
if not container_detail:
|
|
|
- print (f"容器 {container_code} 未组盘")
|
|
|
- logger.error(f"容器 {container_code} 未组盘")
|
|
|
+ print (f"托盘 {container_code} 未组盘")
|
|
|
+ logger.error(f"托盘 {container_code} 未组盘")
|
|
|
return None
|
|
|
- else:
|
|
|
- print (f"容器 {container_code} 已组盘")
|
|
|
+
|
|
|
batch = container_detail.batch.bound_number
|
|
|
return batch
|
|
|
@transaction.atomic
|
|
@@ -536,7 +564,7 @@ class LocationAllocation:
|
|
|
min_c_number_index=1000
|
|
|
|
|
|
current_task = self.get_current_finish_task(container_code)
|
|
|
- print(f"当前已完成任务: {current_task}")
|
|
|
+ print(f"[1]当前已完成任务: {current_task}")
|
|
|
# 按压力排序
|
|
|
sorted_pressure = sorted(
|
|
|
[(0, current_task[0]), (1, current_task[1]), (2, current_task[2])],
|
|
@@ -544,16 +572,16 @@ class LocationAllocation:
|
|
|
)
|
|
|
# 交换第一和第二个元素的位置
|
|
|
sorted_pressure[0], sorted_pressure[1] = sorted_pressure[1], sorted_pressure[0]
|
|
|
- print(f"任务排序: {sorted_pressure}")
|
|
|
- print(f"当前选择:{sorted_pressure[0][0]+1}")
|
|
|
+ print(f"[2]任务排序: {sorted_pressure}")
|
|
|
+ print(f"[3]当前选择:{sorted_pressure[0][0]+1}")
|
|
|
location_type_dict = json.loads(self.divide_solution_by_layer(location_group_list))
|
|
|
- print(f"库位类型分配方案: {location_type_dict}")
|
|
|
+ # print(f"库位类型分配方案: {location_type_dict}")
|
|
|
|
|
|
for layer, _ in sorted_pressure:
|
|
|
if not location_type_dict.get(str(layer+1)):
|
|
|
continue
|
|
|
- print(f"当前层: {layer+1}")
|
|
|
- print(f"当前层库位组: {location_type_dict[str(layer+1)].keys()}")
|
|
|
+ # print(f"当前层: {layer+1}")
|
|
|
+ # print(f"当前层库位组: {location_type_dict[str(layer+1)].keys()}")
|
|
|
for group_id in location_type_dict[str(layer+1)].keys():
|
|
|
location_group = LocationGroupModel.objects.filter(
|
|
|
id=group_id,
|
|
@@ -569,8 +597,11 @@ class LocationAllocation:
|
|
|
# 提取所有库位的 c_number
|
|
|
c_numbers = [loc.c_number for loc in location_list]
|
|
|
print(f"当前层库位组 {location_group.group_code} 可用库位: {c_numbers}")
|
|
|
+ # 更新任务完成数目
|
|
|
+ current_task[layer] = current_task[layer] + 1
|
|
|
+ self.update_current_finish_task(container_code,current_task)
|
|
|
return location_list[0]
|
|
|
-
|
|
|
+ @transaction.atomic
|
|
|
def get_location_type(self, container_code):
|
|
|
"""
|
|
|
智能库位分配核心算法
|
|
@@ -594,7 +625,7 @@ class LocationAllocation:
|
|
|
current_pressure = self.get_current_pressure()
|
|
|
|
|
|
# 测试参数
|
|
|
- total_pallets = 30
|
|
|
+ # total_pallets = 30
|
|
|
# layer_capacity = [{'T1': 29, 'T2': 14, 'S4': 10, 'T4': 27, 'T5': 27}, {'T1': 0, 'T2': 0, 'S4': 0, 'T4': 0, 'T5': 21}, {'T1': 29, 'T2': 14, 'S4': 10, 'T4': 27, 'T5': 27}]
|
|
|
# current_pressure = [1,0,0]
|
|
|
print(f"[1]托盘数目: {total_pallets}")
|
|
@@ -678,7 +709,14 @@ class LocationAllocation:
|
|
|
batch_number=batch,
|
|
|
layer_pre_type =allocation_json
|
|
|
)
|
|
|
- solution_pressure = base_location.objects.get(id=1)
|
|
|
+ solution_pressure, created = base_location.objects.get_or_create(
|
|
|
+ id=1,
|
|
|
+ defaults={
|
|
|
+ 'layer1_pressure': 0,
|
|
|
+ 'layer2_pressure': 0,
|
|
|
+ 'layer3_pressure': 0
|
|
|
+ }
|
|
|
+ )
|
|
|
solution_pressure.layer1_pressure = allocation[1][0]
|
|
|
solution_pressure.layer2_pressure = allocation[1][1]
|
|
|
solution_pressure.layer3_pressure = allocation[1][2]
|
|
@@ -686,6 +724,7 @@ class LocationAllocation:
|
|
|
solution.save()
|
|
|
solution_pressure.save()
|
|
|
|
|
|
+
|
|
|
return [loc.split('_')[1] for loc in allocation[0]]
|
|
|
|
|
|
except Exception as e:
|
|
@@ -742,6 +781,19 @@ class LocationAllocation:
|
|
|
return None
|
|
|
|
|
|
return [solution.layer1_task_finish_number,solution.layer2_task_finish_number,solution.layer3_task_finish_number]
|
|
|
+ def update_current_finish_task(self,container,task_finish_number):
|
|
|
+ batch = self.get_batch(container)
|
|
|
+
|
|
|
+ if not batch:
|
|
|
+ return None
|
|
|
+ solution = alloction_pre.objects.filter(batch_number=batch).first()
|
|
|
+ if not solution:
|
|
|
+ return None
|
|
|
+ solution.layer1_task_finish_number = task_finish_number[0]
|
|
|
+ solution.layer2_task_finish_number = task_finish_number[1]
|
|
|
+ solution.layer3_task_finish_number = task_finish_number[2]
|
|
|
+ solution.save()
|
|
|
+ return True
|
|
|
|
|
|
@transaction.atomic
|
|
|
def get_location_by_type(self, location_type_list, start_location, container_code):
|
|
@@ -761,6 +813,11 @@ class LocationAllocation:
|
|
|
:return: 符合条件的库位列表
|
|
|
"""
|
|
|
locations = []
|
|
|
+ # 检查已有分配方案
|
|
|
+ existing_solution = alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first()
|
|
|
+ if existing_solution.layer_solution_type:
|
|
|
+ print(f"[0]已有库位分配方案:{existing_solution.layer_solution_type}")
|
|
|
+ return existing_solution.layer_solution_type
|
|
|
|
|
|
for layer, location_type_dict in location_type_list.items():
|
|
|
|
|
@@ -769,7 +826,7 @@ class LocationAllocation:
|
|
|
# 获取库位类型列表
|
|
|
location_type = list(location_type_dict.keys())
|
|
|
demand_number = sum(location_type_dict.values())
|
|
|
- print (f"层{layer} 需求数量: {demand_number}, 库位: {location_type}")
|
|
|
+ print (f"[1]层{layer} 需求数量: {demand_number}, 库位: {location_type}")
|
|
|
location_groups = LocationGroupModel.objects.filter(
|
|
|
group_type__in=location_type,
|
|
|
layer=layer,
|
|
@@ -791,7 +848,10 @@ class LocationAllocation:
|
|
|
break
|
|
|
locations.append(f"{layer}_{location_group.id}")
|
|
|
number += 1
|
|
|
-
|
|
|
+
|
|
|
+ existing_solution.layer_solution_type = locations
|
|
|
+ existing_solution.save()
|
|
|
+ print(f"[2]分配方案: {locations}")
|
|
|
return locations if locations else None
|
|
|
|
|
|
|
|
@@ -808,14 +868,15 @@ class LocationAllocation:
|
|
|
#
|
|
|
if status == 1:
|
|
|
# 2. 获取库位组
|
|
|
- print (f"第一次入库")
|
|
|
- self.get_location_type(container_code)
|
|
|
- location_type_list = json.loads(alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first().layer_pre_type)
|
|
|
- print(f"库组分配方案:{location_type_list}")
|
|
|
+ print(f"[1]第一次入库")
|
|
|
+
|
|
|
+ # 重新获取最新数据
|
|
|
+ self.get_location_type(container_code)
|
|
|
+
|
|
|
+ location_type_list = json.loads(alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first().layer_pre_type)
|
|
|
location_list = self.get_location_by_type(location_type_list,start_location,container_code)
|
|
|
- print(f"库组列表:{location_list}")
|
|
|
# 预定这些库组
|
|
|
-
|
|
|
+ self.update_group_status_reserved(location_list)
|
|
|
location_min_value = self.get_location_list_remainder(location_list,container_code)
|
|
|
print(f"库位安排到第{location_min_value.c_number}个库位:{location_min_value}")
|
|
|
# if not location_list[location_min_index]:
|
|
@@ -824,13 +885,15 @@ class LocationAllocation:
|
|
|
# else:
|
|
|
|
|
|
# return location_list[location_min_index]
|
|
|
- return 1
|
|
|
+ return location_min_value
|
|
|
|
|
|
elif status == 2:
|
|
|
# 3. 获取部分入库库位
|
|
|
print (f"部分入库")
|
|
|
- location_list = self.get_location_by_status_part(container_code,start_location)
|
|
|
- print(f"库位列表:{location_list}")
|
|
|
+ location_list = alloction_pre.objects.filter(batch_number=self.get_batch(container_code)).first().layer_solution_type
|
|
|
+ location_min_value = self.get_location_list_remainder(location_list,container_code)
|
|
|
+ print(f"库位安排到第{location_min_value.c_number}个库位:{location_min_value}")
|
|
|
+ return location_min_value
|
|
|
|
|
|
|
|
|
|