LocationAllocationStrategy.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. package com.ruoyi.ams.config.service;
  2. import com.ruoyi.ams.config.domain.dto.InWarehouseDTO;
  3. import com.ruoyi.ams.config.domain.dto.LotattDTO;
  4. import com.ruoyi.ams.config.domain.dto.OutWarehouseDTO;
  5. import com.ruoyi.ams.config.domain.vo.LocationPriorityDetailsVO;
  6. import com.ruoyi.ams.config.domain.vo.LocationPriorityHeaderVO;
  7. import com.ruoyi.ams.config.mapper.LocationPriorityHeaderMapper;
  8. import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper;
  9. import com.ruoyi.base.domain.BaseLocationInfo;
  10. import com.ruoyi.base.domain.LotattVO;
  11. import com.ruoyi.base.domain.vo.BaseLocationLotattVO;
  12. import com.ruoyi.base.mapper.BaseLocationInfoMapper;
  13. import org.springframework.beans.BeanUtils;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.stereotype.Component;
  16. import java.util.ArrayList;
  17. import java.util.LinkedHashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. /**
  21. * Created by IntelliJ IDEA.
  22. * User: andy.qu
  23. * Date: 2022/3/1
  24. */
  25. @Component
  26. public class LocationAllocationStrategy {
  27. @Autowired
  28. private BaseLocationInfoMapper baseLocationInfoMapper;
  29. @Autowired
  30. private LocationPriorityHeaderMapper locationPriorityHeaderMapper;
  31. @Autowired
  32. private InvLotLocIdMapper invLotLocIdMapper;
  33. /**
  34. * 过滤锁定库位
  35. *
  36. * @param baseLocationInfos
  37. * @return
  38. */
  39. public BaseLocationInfo filterLockLocation(List<BaseLocationInfo> baseLocationInfos) {
  40. //将同一列的库位排序好
  41. LinkedHashMap<String, List<BaseLocationInfo>> map = new LinkedHashMap<>();
  42. for (BaseLocationInfo info : baseLocationInfos) {
  43. List<BaseLocationInfo> infoList;
  44. if (map.containsKey(info.getColNo())) {
  45. infoList = map.get(info.getColNo());
  46. } else {
  47. infoList = new ArrayList<>();
  48. }
  49. infoList.add(info);
  50. map.put(info.getColNo(), infoList);
  51. }
  52. //过滤出每列可以用的库位并进行分配
  53. BaseLocationInfo currentLocation = null;
  54. for (Map.Entry<String, List<BaseLocationInfo>> entry : map.entrySet()) {
  55. List<BaseLocationInfo> locationInfoList = entry.getValue();
  56. for (BaseLocationInfo b : locationInfoList) {
  57. if (currentLocation == null) {
  58. if (b.getIsEmpty().equals("Y") && b.getStockStatus().equals("00")) {
  59. currentLocation = b;
  60. }
  61. } else {
  62. //如果前面的库位已阻挡则之前的库位不可用
  63. if (!b.getIsEmpty().equals("Y") || !b.getStockStatus().equals("00")) {
  64. currentLocation = null;
  65. } else {
  66. continue;
  67. }
  68. }
  69. }
  70. if (currentLocation != null) {
  71. break;
  72. }
  73. }
  74. return currentLocation;
  75. }
  76. /**
  77. * 根据策略过滤锁定库位
  78. *
  79. * @param zoneId 入库区域
  80. * @param inWarehouseDTO 入库信息
  81. * @param locationPriorityHeaderVO 出入库策略
  82. * @return
  83. */
  84. public BaseLocationInfo filterLockLocation(Long zoneId, InWarehouseDTO inWarehouseDTO, LocationPriorityHeaderVO locationPriorityHeaderVO) {
  85. BaseLocationInfo query = new BaseLocationInfo();
  86. query.setWarehouseId(inWarehouseDTO.getWarehouseId());
  87. query.setZoneId(zoneId);
  88. List<BaseLocationLotattVO> locationLotattVOList = baseLocationInfoMapper.selectSortedLocationLotattListByZoneId(query);
  89. List<LocationPriorityDetailsVO> locationPriorityDetails = locationPriorityHeaderMapper.selectLocationPriorityDetailsList(locationPriorityHeaderVO.getId());
  90. //批次属性
  91. LinkedHashMap<String, String> lotatt = new LinkedHashMap<>();
  92. if (locationPriorityDetails != null && locationPriorityDetails.size() > 0) {
  93. for (LocationPriorityDetailsVO vo : locationPriorityDetails) {
  94. lotatt.put(vo.getLotattId(), vo.getLotattValue());
  95. }
  96. }
  97. //如果策略配置了入库的属性那么选择相同属性的库位进行存放
  98. if (lotatt.size() > 0 && inWarehouseDTO.getLotattDTO() != null) {
  99. LotattDTO lotattDTO = inWarehouseDTO.getLotattDTO();
  100. lotattDTO.getAttr();
  101. boolean isSame = true;
  102. for (Map.Entry<String, String> attEntry : lotatt.entrySet()) {
  103. if (lotattDTO.getAttr().get(attEntry.getKey()) != null) {
  104. if (!lotattDTO.getAttr().get(attEntry.getKey()).equals(attEntry.getValue())) {
  105. isSame = false;
  106. }
  107. }
  108. }
  109. if (isSame == false) {
  110. return null;
  111. }
  112. }
  113. //将同一列的库位排序好
  114. Integer parallelCount = 0;
  115. LinkedHashMap<String, Boolean> taskingFlag = new LinkedHashMap<>();
  116. LinkedHashMap<String, List<BaseLocationLotattVO>> map = new LinkedHashMap<>();
  117. for (BaseLocationLotattVO info : locationLotattVOList) {
  118. List<BaseLocationLotattVO> infoList;
  119. if (map.containsKey(info.getColNo())) {
  120. infoList = map.get(info.getColNo());
  121. } else {
  122. infoList = new ArrayList<>();
  123. }
  124. if (info.getStockStatus().equals("10")) {
  125. taskingFlag.put(info.getColNo(), true);
  126. parallelCount++;
  127. } else {
  128. if (taskingFlag.get(info.getColNo()) == null || taskingFlag.get(info.getColNo()).booleanValue() == false) {
  129. taskingFlag.put(info.getColNo(), false);
  130. }
  131. }
  132. infoList.add(info);
  133. map.put(info.getColNo(), infoList);
  134. }
  135. //过滤出每列可以用的库位并进行分配
  136. BaseLocationInfo currentLocation = null;
  137. for (Map.Entry<String, List<BaseLocationLotattVO>> entry : map.entrySet()) {
  138. List<BaseLocationLotattVO> locationInfoList = entry.getValue();
  139. for (BaseLocationLotattVO b : locationInfoList) {
  140. //如果允许并行则跳过已经分配过的列
  141. if (locationPriorityHeaderVO.getParallelFlag().equals("Y")) {
  142. //如果达到并行数量,则当前区域不再进行分配
  143. if (parallelCount + 1 > locationPriorityHeaderVO.getParallelCount()) {
  144. return null;
  145. }
  146. if (taskingFlag.get(b.getColNo())) {
  147. continue;
  148. }
  149. }
  150. // TODO 如果库存中已存在批次属性那么存放相同批次属性的物料
  151. /*if (lotatt.size() > 0) { //指定了批次属性的需要对相同批次属性的库存进行匹配
  152. //如果没有批次属性查询是否有待搬运的属性
  153. if (b.getLotattVO() == null) {
  154. LotattVO lotattVO = baseLocationInfoMapper.selectInvLotattById(b.getId());
  155. b.setLotattVO(lotattVO);
  156. }
  157. b.initLotatt();
  158. boolean isSame = true;
  159. for (Map.Entry<String, String> attEntry : lotatt.entrySet()) {
  160. if (!b.getAttMap().get(attEntry.getKey()).equals(attEntry.getValue())) {
  161. isSame = false;
  162. }
  163. }
  164. if (isSame == false) {
  165. continue;
  166. }
  167. }*/
  168. if (currentLocation == null) {
  169. if (b.getIsEmpty().equals("Y") && b.getStockStatus().equals("00")) {
  170. BaseLocationInfo locationInfo = new BaseLocationInfo();
  171. BeanUtils.copyProperties(b, locationInfo);
  172. currentLocation = locationInfo;
  173. }
  174. } else {
  175. //如果前面的库位已阻挡则之前的库位不可用
  176. if (!b.getIsEmpty().equals("Y") || !b.getStockStatus().equals("00")) {
  177. currentLocation = null;
  178. } else {
  179. continue;
  180. }
  181. }
  182. }
  183. if (currentLocation != null) {
  184. break;
  185. }
  186. }
  187. return currentLocation;
  188. }
  189. /**
  190. * 过滤出库
  191. *
  192. * @param zoneId
  193. * @param outWarehouseDTO
  194. * @param locationPriorityHeaderVO
  195. * @return
  196. */
  197. public BaseLocationInfo filterLockInv(Long zoneId, OutWarehouseDTO outWarehouseDTO, LocationPriorityHeaderVO locationPriorityHeaderVO) {
  198. List<BaseLocationLotattVO> locationLotattVOList = invLotLocIdMapper.selectInvLocationList(zoneId, outWarehouseDTO.getSku(), outWarehouseDTO.getSkuType(), 0D, "", outWarehouseDTO.getLotattDTO());
  199. List<LocationPriorityDetailsVO> locationPriorityDetails = null;
  200. LinkedHashMap<String, String> lotatt = new LinkedHashMap<>();
  201. if (locationPriorityHeaderVO != null) {
  202. locationPriorityDetails = locationPriorityHeaderMapper.selectLocationPriorityDetailsList(locationPriorityHeaderVO.getId());
  203. //批次属性
  204. if (locationPriorityDetails != null && locationPriorityDetails.size() > 0) {
  205. for (LocationPriorityDetailsVO vo : locationPriorityDetails) {
  206. lotatt.put(vo.getLotattId(), vo.getLotattValue());
  207. }
  208. }
  209. }
  210. //将同一列的库位排序好
  211. Integer parallelCount = 0;
  212. LinkedHashMap<String, Boolean> taskingFlag = new LinkedHashMap<>();
  213. LinkedHashMap<String, List<BaseLocationLotattVO>> map = new LinkedHashMap<>();
  214. for (BaseLocationLotattVO info : locationLotattVOList) {
  215. List<BaseLocationLotattVO> infoList;
  216. if (map.containsKey(info.getColNo())) {
  217. infoList = map.get(info.getColNo());
  218. } else {
  219. infoList = new ArrayList<>();
  220. }
  221. if (info.getStockStatus().equals("10")) {
  222. taskingFlag.put(info.getColNo(), true);
  223. parallelCount++;
  224. } else {
  225. if (taskingFlag.get(info.getColNo()) == null || taskingFlag.get(info.getColNo()).booleanValue() == false) {
  226. taskingFlag.put(info.getColNo(), false);
  227. }
  228. }
  229. infoList.add(info);
  230. map.put(info.getColNo(), infoList);
  231. }
  232. //TODO 近效期
  233. //过滤出每列可以用的库位并进行分配
  234. BaseLocationInfo currentLocation = null;
  235. for (Map.Entry<String, List<BaseLocationLotattVO>> entry : map.entrySet()) {
  236. List<BaseLocationLotattVO> locationInfoList = entry.getValue();
  237. for (BaseLocationLotattVO b : locationInfoList) {
  238. if (locationPriorityHeaderVO.getSameLotattFlag().equals("N")) {
  239. //如果外围优先则跳过当前出
  240. if (locationPriorityHeaderVO.getOuterFlag().equals("Y")) {
  241. if (taskingFlag.get(b.getColNo())) {
  242. continue;
  243. }
  244. }
  245. }
  246. /*if (locationPriorityHeaderVO.getParallelFlag().equals("Y")) {
  247. //如果达到并行数量,则当前区域不再进行分配
  248. if (parallelCount + 1 > locationPriorityHeaderVO.getParallelCount()) {
  249. return null;
  250. }
  251. if (taskingFlag.get(b.getColNo())) {
  252. continue;
  253. }
  254. }*/
  255. if (currentLocation == null) {
  256. if (b.getIsEmpty().equals("N") && b.getStockStatus().equals("00")) {
  257. BaseLocationInfo locationInfo = new BaseLocationInfo();
  258. BeanUtils.copyProperties(b, locationInfo);
  259. currentLocation = locationInfo;
  260. }
  261. } else {
  262. //如果前面的库位已阻挡则之前的库位不可用
  263. if (!b.getIsEmpty().equals("Y") || !b.getStockStatus().equals("00")) {
  264. currentLocation = null;
  265. } else {
  266. continue;
  267. }
  268. }
  269. }
  270. if (currentLocation != null) {
  271. break;
  272. }
  273. }
  274. return currentLocation;
  275. }
  276. }