queries.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. from django.db import models
  2. from .models import *
  3. from django.db.models import Q
  4. import json
  5. from django.db import transaction
  6. from container.models import *
  7. from .models import LocationGroupModel
  8. import logging
  9. from collections import defaultdict
  10. logger = logging.getLogger(__name__)
  11. class LocationQueries:
  12. """"
  13. 库位相关查询
  14. functions:
  15. get_container(container_code): 获取托盘信息
  16. params: container_code: 托盘编号
  17. return: ContainerListModel
  18. get_active_container_details(container_id): 获取托盘详情
  19. params: container_id: 托盘ID
  20. return: ContainerDetailModel
  21. get_active_container_details(container_id): 获取托盘详情
  22. params: container_id: 托盘ID
  23. return: ContainerDetailModel
  24. get_batch_info(container_code): 获取托盘批次信息
  25. params: container_code: 托盘编号
  26. return: dict
  27. get_group_capacity(): 获取库位组空闲容量
  28. return: list
  29. get_current_pressure(): 获取仓库当前工作压力
  30. return: list
  31. get_pallet_count(container_code): 获取托盘数量
  32. params: container_code: 托盘编号
  33. return: int
  34. """
  35. @staticmethod
  36. def get_container(container_code):
  37. return ContainerListModel.objects.filter(container_code=container_code).first()
  38. @staticmethod
  39. def get_active_container_details(container_id):
  40. return ContainerDetailModel.objects.filter(
  41. container=container_id
  42. ).exclude(status=3).first()
  43. @staticmethod
  44. def get_batch_info(container_code):
  45. container = ContainerListModel.objects.filter(
  46. container_code=container_code
  47. ).first()
  48. if not container:
  49. return None
  50. detail = ContainerDetailModel.objects.filter(
  51. container=container.id
  52. ).exclude(status=3).first()
  53. if not detail:
  54. return {
  55. 'status': None,
  56. 'number': None,
  57. 'container': container,
  58. 'class': 2 ,
  59. }
  60. return {
  61. 'status': detail.batch.status if detail.batch else None,
  62. 'number': detail.batch.bound_number if detail.batch else None,
  63. 'container': container,
  64. 'class': detail.goods_class if detail else None,
  65. }
  66. @staticmethod
  67. def get_group_capacity():
  68. groups = ['T1', 'T2', 'S4', 'T4', 'T5']
  69. capacity = []
  70. for layer in [1, 2, 3]:
  71. layer_data = {}
  72. for group in groups:
  73. count = LocationGroupModel.objects.filter(
  74. group_type=group,
  75. layer=layer,
  76. status='available'
  77. ).count()
  78. layer_data[group] = count
  79. capacity.append(layer_data)
  80. return capacity
  81. @staticmethod
  82. def get_current_pressure():
  83. pressure = base_location.objects.first()
  84. if not pressure:
  85. pressure = base_location.objects.create()
  86. return [pressure.layer1_pressure, pressure.layer2_pressure, pressure.layer3_pressure]
  87. @staticmethod
  88. def get_pallet_count(container_code):
  89. """
  90. 获取托盘数量
  91. :param container_code: 要查询的托盘码
  92. :return: 所属批次下的托盘总数
  93. """
  94. # 1. 通过托盘码获取容器详情
  95. container = ContainerListModel.objects.filter(
  96. container_code=container_code
  97. ).first()
  98. if not container:
  99. logger.error(f"托盘 {container_code} 不存在")
  100. return None
  101. container_detail = ContainerDetailModel.objects.filter(
  102. container=container.id
  103. ).exclude(status = 3).first()
  104. batch_obj = container_detail.batch
  105. return batch_obj.container_number
  106. @staticmethod
  107. def get_pallet_count_by_batch( container_code):
  108. """
  109. 根据托盘码查询批次下托盘总数
  110. :param container_code: 要查询的托盘码
  111. :return: 所属批次下的托盘总数
  112. """
  113. # 1. 通过托盘码获取容器详情
  114. container = ContainerListModel.objects.filter(
  115. container_code=container_code
  116. ).first()
  117. if not container:
  118. logger.error(f"托盘 {container_code} 不存在")
  119. return None
  120. container_detail = ContainerDetailModel.objects.filter(
  121. container=container.id
  122. ).exclude(status = 3).first()
  123. if not container_detail:
  124. logger.error(f"托盘 {container_code} 未组盘")
  125. return None
  126. batch_container = ContainerDetailModel.objects.filter(
  127. batch = container_detail.batch.id,
  128. ).all().exclude(status = 3)
  129. # 统计批次下的不同托盘 item.contianer_id
  130. batch_container_count = 0
  131. container_ids = []
  132. for item in batch_container:
  133. if item.container_id not in container_ids:
  134. batch_container_count = batch_container_count + 1
  135. container_ids.append(item.container_id)
  136. return batch_container_count
  137. @staticmethod
  138. def get_current_finish_task(container,batch_info):
  139. batch = batch_info.get('number')
  140. if not batch:
  141. return None
  142. solution = alloction_pre.objects.filter(batch_number=batch).first()
  143. if not solution:
  144. return None
  145. return [solution.layer1_task_finish_number,solution.layer2_task_finish_number,solution.layer3_task_finish_number]
  146. @staticmethod
  147. def divide_solution_by_layer(data):
  148. # 统计所有存在的层级
  149. layer_counts = defaultdict(lambda: defaultdict(int))
  150. existing_layers = set()
  151. for item in data:
  152. # 分割层级和类型
  153. try:
  154. layer, loc_type = item.split('_')
  155. layer_num = int(layer)
  156. existing_layers.add(layer_num)
  157. layer_counts[layer_num][loc_type] += 1
  158. except (ValueError, IndexError):
  159. continue # 跳过无效格式的数据
  160. # 确定最大层级(至少包含1层)
  161. max_layer = max(existing_layers) if existing_layers else 1
  162. # 构建包含所有层级的最终结果
  163. final_result = {}
  164. for layer in range(1, max_layer + 1):
  165. final_result[str(layer)] = dict(layer_counts.get(layer, {}))
  166. return json.dumps(final_result, indent=2)
  167. @staticmethod
  168. def get_alloction_pre_solution(batch_number):
  169. """
  170. 获取指定批次的预留方案
  171. :param batch_number: 批次号
  172. :return: 预留方案
  173. """
  174. solution = alloction_pre.objects.filter(batch_number=batch_number).first()
  175. if not solution:
  176. return None
  177. return solution.layer_solution_type
  178. @staticmethod
  179. def get_left_location_group(batch_number):
  180. """
  181. 获取指定批次的剩余库位
  182. :param batch_number: 批次号
  183. :return: 剩余库位
  184. """
  185. layer_solution_type =[]
  186. location_group_obj =LocationGroupModel.objects.filter(current_batch=batch_number,status='occupied').all()
  187. if not location_group_obj:
  188. return None
  189. else:
  190. for item in location_group_obj:
  191. layer_solution_type.append(f"{item.layer}_{item.id}")
  192. return layer_solution_type