|
@@ -1,16 +1,20 @@
|
|
|
package com.ruoyi.ams.config.service;
|
|
|
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
import com.ruoyi.ams.business.domain.LocationSortComparator;
|
|
|
import com.ruoyi.ams.business.domain.LocationSortDTO;
|
|
|
import com.ruoyi.ams.config.domain.AsnSoStrategy;
|
|
|
import com.ruoyi.ams.config.domain.dto.InWarehouseDTO;
|
|
|
import com.ruoyi.ams.config.domain.dto.OutWarehouseDTO;
|
|
|
import com.ruoyi.base.domain.BaseLocationInfo;
|
|
|
+import com.ruoyi.base.domain.vo.BaseLocationLotattListVO;
|
|
|
import com.ruoyi.base.domain.vo.BaseLocationLotattVO;
|
|
|
+import com.ruoyi.base.domain.vo.LotattInfo;
|
|
|
import com.ruoyi.base.service.IBaseLocationInfoService;
|
|
|
import com.ruoyi.common.core.redis.RedisCache;
|
|
|
import com.ruoyi.common.core.redis.RedisKey;
|
|
|
import com.ruoyi.common.utils.StringUtils;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -23,6 +27,7 @@ import java.util.*;
|
|
|
* User: andy.qu
|
|
|
* Date: 2022/3/1
|
|
|
*/
|
|
|
+@Slf4j
|
|
|
@Component
|
|
|
public class LocationAllocationStrategy {
|
|
|
|
|
@@ -336,4 +341,149 @@ public class LocationAllocationStrategy {
|
|
|
}
|
|
|
return currentLocation;
|
|
|
}
|
|
|
+
|
|
|
+ private Double checkOutedInvQty(OutWarehouseDTO ow, Map<String, List<LotattInfo>> lockInvList) {
|
|
|
+ Double qty = 0d;
|
|
|
+ for (Map.Entry<String, List<LotattInfo>> entry : lockInvList.entrySet()) {
|
|
|
+ List<LotattInfo> list = entry.getValue();
|
|
|
+ for (LotattInfo info : list) {
|
|
|
+ if (info.getSku().equals(ow.getSku())) {
|
|
|
+ qty += info.getQty();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return qty;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 过滤库存信息
|
|
|
+ *
|
|
|
+ * @param locationIdList 库位id列表
|
|
|
+ * @param outWarehouseDTOs 物料
|
|
|
+ * @param asnSoStrategy 策略
|
|
|
+ * @param token 唯一token用来解锁加锁
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public List<BaseLocationInfo> filterLockInv(List<Long> locationIdList, List<OutWarehouseDTO> outWarehouseDTOs, AsnSoStrategy asnSoStrategy, Long token) {
|
|
|
+ //取出范围内所有的库存
|
|
|
+ List<BaseLocationLotattListVO> locationLotattVOList = baseLocationInfoService.selectSortedLocatinListByZoneId(locationIdList, 1L, null, null);
|
|
|
+ List<BaseLocationInfo> result = new ArrayList<>(); //返回的结果
|
|
|
+ Map<String, List<LotattInfo>> lockInv = new HashMap<>(); //已锁定的库存列表(key:列名,value:库位库存)
|
|
|
+ //将同一列的库位排序好====================================================>
|
|
|
+ LinkedHashMap<String, Boolean> taskingFlag = new LinkedHashMap<>(); //任务中的列
|
|
|
+ LinkedHashMap<String, List<BaseLocationLotattListVO>> mapFloor = new LinkedHashMap<>(); //同一列的库存(key:列名,value:库位库存)地堆
|
|
|
+ LinkedHashMap<String, List<BaseLocationLotattListVO>> shelvesFloor = new LinkedHashMap<>(); //同一列的库存(key:列名,value:库位库存)货架
|
|
|
+ LinkedHashMap<String, String> skuTagMap = new LinkedHashMap<>(); //每列存放的物料分类(key:列名,value:sku)
|
|
|
+ List<LocationSortDTO> list = new ArrayList<>();//全部
|
|
|
+ List<LocationSortDTO> sameLotattList = new ArrayList<>(); //同批号
|
|
|
+ for (BaseLocationLotattListVO info : locationLotattVOList) {
|
|
|
+ List<BaseLocationLotattListVO> infoList;
|
|
|
+ if (info.getLocationType().equals("1")) {
|
|
|
+ if (shelvesFloor.containsKey(info.getColNo())) {
|
|
|
+ infoList = shelvesFloor.get(info.getColNo());
|
|
|
+ } else {
|
|
|
+ infoList = new ArrayList<>();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (mapFloor.containsKey(info.getColNo())) {
|
|
|
+ infoList = mapFloor.get(info.getColNo());
|
|
|
+ } else {
|
|
|
+ infoList = new ArrayList<>();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info.getColNo() != null) {
|
|
|
+ if (skuTagMap.containsKey(info.getColNo())) {
|
|
|
+ String tmp = skuTagMap.get(info.getColNo());
|
|
|
+ StringBuffer sb = new StringBuffer(tmp);
|
|
|
+ List<LotattInfo> lotattInfoList = info.getLotattInfoList();
|
|
|
+ if (info.getLotattInfoList() != null && info.getLotattInfoList().size() > 0) {
|
|
|
+ for (LotattInfo lot : lotattInfoList) {
|
|
|
+ if (lot.getSku() == null || tmp.contains(lot.getSku())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ sb.append(",");
|
|
|
+ sb.append(lot.getSku());
|
|
|
+ }
|
|
|
+ if (sb.length() > 0) {
|
|
|
+ skuTagMap.put(info.getColNo(), sb.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ StringBuffer sb = new StringBuffer("");
|
|
|
+ List<LotattInfo> lotattInfoList = info.getLotattInfoList();
|
|
|
+ if (info.getLotattInfoList() != null && info.getLotattInfoList().size() > 0) {
|
|
|
+ for (LotattInfo lot : lotattInfoList) {
|
|
|
+ if (lot.getSku() == null || sb.toString().contains(lot.getSku())) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ sb.append(",");
|
|
|
+ sb.append(lot.getSku());
|
|
|
+ }
|
|
|
+ if (sb.length() > 0) {
|
|
|
+ skuTagMap.put(info.getColNo(), sb.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (info.getStockStatus().equals("10") || redisCache.checkIsLock(RedisKey.LOCK_LOCATION + info.getId())) {
|
|
|
+ taskingFlag.put(info.getColNo(), true);
|
|
|
+ lockInv.put(info.getId().toString(), info.getLotattInfoList());
|
|
|
+ //如果在任务中跳过该库存
|
|
|
+ } else {
|
|
|
+ if (taskingFlag.get(info.getColNo()) == null || taskingFlag.get(info.getColNo()).booleanValue() == false) {
|
|
|
+ taskingFlag.put(info.getColNo(), false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ infoList.add(info);
|
|
|
+ if (info.getLocationType().equals("1")) {
|
|
|
+ mapFloor.put(info.getColNo(), infoList);
|
|
|
+ } else {
|
|
|
+ shelvesFloor.put(info.getColNo(), infoList);
|
|
|
+ }
|
|
|
+
|
|
|
+ String period = "";
|
|
|
+ if (asnSoStrategy.getSoPeriodFlag().equals("optimization") || asnSoStrategy.getSoPeriodFlag().equals("force")) {
|
|
|
+ info.getLotattInfoList().get(0).initLotatt();
|
|
|
+ period = info.getLotattInfoList().get(0).getAttMap().get(asnSoStrategy.getSoPeriodLotatt());
|
|
|
+ }
|
|
|
+ LocationSortDTO sortDTO = new LocationSortDTO(info.getColNo(), period);
|
|
|
+ list.add(sortDTO);
|
|
|
+
|
|
|
+ if (asnSoStrategy.getSoSameLotatt1Flag().equals("optimization")) {
|
|
|
+ String lotattValue = redisCache.getCacheObject(asnSoStrategy.getAsnSameLotatt1Value());
|
|
|
+ if (!StringUtils.isEmpty(lotattValue)) {
|
|
|
+ if (!StringUtils.isEmpty(info.getLotattInfoList().get(0).getAttMap().get(asnSoStrategy.getSoSameLotatt1Value())) && info.getLotattInfoList().get(0).getAttMap().get(asnSoStrategy.getSoSameLotatt1Value()).equals(lotattValue)) {
|
|
|
+ sameLotattList.add(sortDTO);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //=========================================================>
|
|
|
+ log.info("检索的库存范围:" + JSON.toJSONString(locationLotattVOList));
|
|
|
+ log.info("列的任务状态:" + JSON.toJSONString(taskingFlag));
|
|
|
+ log.info("每列存放的物料分类:" + JSON.toJSONString(skuTagMap));
|
|
|
+
|
|
|
+ for (OutWarehouseDTO ow : outWarehouseDTOs) {
|
|
|
+ //先去已锁定的库存中查询是否有可以扣减的库存
|
|
|
+ Double qty = checkOutedInvQty(ow, lockInv);
|
|
|
+ if (qty >= ow.getQty()) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ //过滤出每列可以用的库位并进行分配
|
|
|
+ BaseLocationInfo currentLocation = null;
|
|
|
+ BaseLocationLotattListVO currentLocationLotatt = null;
|
|
|
+ //地堆
|
|
|
+ for (Map.Entry<String, List<BaseLocationLotattListVO>> invList : mapFloor.entrySet()) {
|
|
|
+
|
|
|
+ }
|
|
|
+ //货架
|
|
|
+ for (Map.Entry<String, List<BaseLocationLotattListVO>> invList : shelvesFloor.entrySet()) {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|