queries.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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,is_delete=False
  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. detail = ContainerDetailModel.objects.filter(
  49. container=container.id,is_delete=False
  50. ).exclude(status=3).first()
  51. if not detail:
  52. return {
  53. 'status': None,
  54. 'number': None,
  55. 'container': container,
  56. 'class': 2 ,
  57. }
  58. elif detail.batch is None:
  59. return {
  60. 'status': None,
  61. 'number': None,
  62. 'container': container,
  63. 'class': 2,
  64. }
  65. else:
  66. detail_all = ContainerDetailModel.objects.filter(
  67. container=container.id,is_delete=False
  68. ).exclude(status=3).all()
  69. # 统计该拖盘上的不同批次数目
  70. batch_count = len(set([item.batch.id for item in detail_all]))
  71. if batch_count > 1:
  72. for item in detail_all:
  73. item.goods_class = 3
  74. item.save()
  75. return {
  76. 'status': None,
  77. 'number': None,
  78. 'container': container,
  79. 'class': 3,
  80. }
  81. else:
  82. return {
  83. 'status': detail.batch.status ,
  84. 'number': detail.batch.bound_number ,
  85. 'container': container,
  86. 'class': 1,
  87. }
  88. @staticmethod
  89. def get_group_capacity():
  90. groups = ['T1', 'T2', 'S4', 'T4', 'T5']
  91. capacity = []
  92. for layer in [1, 2, 3]:
  93. layer_data = {}
  94. for group in groups:
  95. count = LocationGroupModel.objects.filter(
  96. group_type=group,
  97. layer=layer,
  98. status='available'
  99. ).count()
  100. layer_data[group] = count
  101. capacity.append(layer_data)
  102. return capacity
  103. @staticmethod
  104. def get_current_pressure():
  105. pressure = base_location.objects.first()
  106. if not pressure:
  107. pressure = base_location.objects.create()
  108. return [pressure.layer1_pressure, pressure.layer2_pressure, pressure.layer3_pressure]
  109. @staticmethod
  110. def get_pallet_count(container_code):
  111. """
  112. 获取托盘数量
  113. :param container_code: 要查询的托盘码
  114. :return: 所属批次下的托盘总数
  115. """
  116. # 1. 通过托盘码获取容器详情
  117. container = ContainerListModel.objects.filter(
  118. container_code=container_code
  119. ).first()
  120. if not container:
  121. logger.error(f"托盘 {container_code} 不存在")
  122. return None
  123. container_detail = ContainerDetailModel.objects.filter(
  124. container=container.id,is_delete=False
  125. ).exclude(status = 3).first()
  126. batch_obj = container_detail.batch
  127. return batch_obj.container_number
  128. @staticmethod
  129. def get_pallet_count_by_batch( container_code):
  130. """
  131. 根据托盘码查询批次下托盘总数
  132. :param container_code: 要查询的托盘码
  133. :return: 所属批次下的托盘总数
  134. """
  135. # 1. 通过托盘码获取容器详情
  136. container = ContainerListModel.objects.filter(
  137. container_code=container_code
  138. ).first()
  139. if not container:
  140. logger.error(f"托盘 {container_code} 不存在")
  141. return None
  142. container_detail = ContainerDetailModel.objects.filter(
  143. container=container.id,is_delete=False
  144. ).exclude(status = 3).first()
  145. if not container_detail:
  146. logger.error(f"托盘 {container_code} 未组盘")
  147. return None
  148. batch_container = ContainerDetailModel.objects.filter(
  149. batch = container_detail.batch.id,is_delete=False
  150. ).all().exclude(status = 3)
  151. # 统计批次下的不同托盘 item.contianer_id
  152. batch_container_count = 0
  153. container_ids = []
  154. for item in batch_container:
  155. if item.container_id not in container_ids:
  156. batch_container_count = batch_container_count + 1
  157. container_ids.append(item.container_id)
  158. return batch_container_count
  159. @staticmethod
  160. def get_current_finish_task(container,batch_info):
  161. batch = batch_info.get('number')
  162. if not batch:
  163. return None
  164. solution = alloction_pre.objects.filter(batch_number=batch).first()
  165. if not solution:
  166. return None
  167. return [solution.layer1_task_finish_number,solution.layer2_task_finish_number,solution.layer3_task_finish_number]
  168. @staticmethod
  169. def divide_solution_by_layer(data):
  170. # 统计所有存在的层级
  171. layer_counts = defaultdict(lambda: defaultdict(int))
  172. existing_layers = set()
  173. for item in data:
  174. # 分割层级和类型
  175. try:
  176. layer, loc_type = item.split('_')
  177. layer_num = int(layer)
  178. existing_layers.add(layer_num)
  179. layer_counts[layer_num][loc_type] += 1
  180. except (ValueError, IndexError):
  181. continue # 跳过无效格式的数据
  182. # 确定最大层级(至少包含1层)
  183. max_layer = max(existing_layers) if existing_layers else 1
  184. # 构建包含所有层级的最终结果
  185. final_result = {}
  186. for layer in range(1, max_layer + 1):
  187. final_result[str(layer)] = dict(layer_counts.get(layer, {}))
  188. return json.dumps(final_result, indent=2)
  189. @staticmethod
  190. def get_alloction_pre_solution(batch_number):
  191. """
  192. 获取指定批次的预留方案
  193. :param batch_number: 批次号
  194. :return: 预留方案
  195. """
  196. solution = alloction_pre.objects.filter(batch_number=batch_number).first()
  197. if not solution:
  198. return None
  199. return solution.layer_solution_type
  200. @staticmethod
  201. def get_left_location_group(batch_number):
  202. """
  203. 获取指定批次的剩余库位
  204. :param batch_number: 批次号
  205. :return: 剩余库位
  206. """
  207. layer_solution_type =[]
  208. location_group_obj =LocationGroupModel.objects.filter(current_batch=batch_number,status='occupied').all()
  209. if not location_group_obj:
  210. return None
  211. else:
  212. for item in location_group_obj:
  213. layer_solution_type.append(f"{item.layer}_{item.id}")
  214. return layer_solution_type