package com.ruoyi.ams.config.service; import com.ruoyi.ams.config.domain.dto.InWarehouseDTO; import com.ruoyi.ams.config.domain.dto.LotattDTO; import com.ruoyi.ams.config.domain.dto.OutWarehouseDTO; import com.ruoyi.ams.config.domain.vo.LocationPriorityDetailsVO; import com.ruoyi.ams.config.domain.vo.LocationPriorityHeaderVO; import com.ruoyi.ams.config.mapper.LocationPriorityHeaderMapper; import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper; import com.ruoyi.base.domain.BaseLocationInfo; import com.ruoyi.base.domain.LotattVO; import com.ruoyi.base.domain.vo.BaseLocationLotattVO; import com.ruoyi.base.mapper.BaseLocationInfoMapper; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * Created by IntelliJ IDEA. * User: andy.qu * Date: 2022/3/1 */ @Component public class LocationAllocationStrategy { @Autowired private BaseLocationInfoMapper baseLocationInfoMapper; @Autowired private LocationPriorityHeaderMapper locationPriorityHeaderMapper; @Autowired private InvLotLocIdMapper invLotLocIdMapper; /** * 过滤锁定库位 * * @param baseLocationInfos * @return */ public BaseLocationInfo filterLockLocation(List baseLocationInfos) { //将同一列的库位排序好 LinkedHashMap> map = new LinkedHashMap<>(); for (BaseLocationInfo info : baseLocationInfos) { List infoList; if (map.containsKey(info.getColNo())) { infoList = map.get(info.getColNo()); } else { infoList = new ArrayList<>(); } infoList.add(info); map.put(info.getColNo(), infoList); } //过滤出每列可以用的库位并进行分配 BaseLocationInfo currentLocation = null; for (Map.Entry> entry : map.entrySet()) { List locationInfoList = entry.getValue(); for (BaseLocationInfo b : locationInfoList) { if (currentLocation == null) { if (b.getIsEmpty().equals("Y") && b.getStockStatus().equals("00")) { currentLocation = b; } } else { //如果前面的库位已阻挡则之前的库位不可用 if (!b.getIsEmpty().equals("Y") || !b.getStockStatus().equals("00")) { currentLocation = null; } else { continue; } } } if (currentLocation != null) { break; } } return currentLocation; } /** * 根据策略过滤锁定库位 * * @param zoneId 入库区域 * @param inWarehouseDTO 入库信息 * @param locationPriorityHeaderVO 出入库策略 * @return */ public BaseLocationInfo filterLockLocation(Long zoneId, InWarehouseDTO inWarehouseDTO, LocationPriorityHeaderVO locationPriorityHeaderVO) { BaseLocationInfo query = new BaseLocationInfo(); query.setWarehouseId(inWarehouseDTO.getWarehouseId()); query.setZoneId(zoneId); List locationLotattVOList = baseLocationInfoMapper.selectSortedLocationLotattListByZoneId(query); List locationPriorityDetails = locationPriorityHeaderMapper.selectLocationPriorityDetailsList(locationPriorityHeaderVO.getId()); //批次属性 LinkedHashMap lotatt = new LinkedHashMap<>(); if (locationPriorityDetails != null && locationPriorityDetails.size() > 0) { for (LocationPriorityDetailsVO vo : locationPriorityDetails) { lotatt.put(vo.getLotattId(), vo.getLotattValue()); } } //如果策略配置了入库的属性那么选择相同属性的库位进行存放 if (lotatt.size() > 0 && inWarehouseDTO.getLotattDTO() != null) { LotattDTO lotattDTO = inWarehouseDTO.getLotattDTO(); lotattDTO.getAttr(); boolean isSame = true; for (Map.Entry attEntry : lotatt.entrySet()) { if (lotattDTO.getAttr().get(attEntry.getKey()) != null) { if (!lotattDTO.getAttr().get(attEntry.getKey()).equals(attEntry.getValue())) { isSame = false; } } } if (isSame == false) { return null; } } //将同一列的库位排序好 Integer parallelCount = 0; LinkedHashMap taskingFlag = new LinkedHashMap<>(); LinkedHashMap> map = new LinkedHashMap<>(); for (BaseLocationLotattVO info : locationLotattVOList) { List infoList; if (map.containsKey(info.getColNo())) { infoList = map.get(info.getColNo()); } else { infoList = new ArrayList<>(); } if (info.getStockStatus().equals("10")) { taskingFlag.put(info.getColNo(), true); parallelCount++; } else { if (taskingFlag.get(info.getColNo()) == null || taskingFlag.get(info.getColNo()).booleanValue() == false) { taskingFlag.put(info.getColNo(), false); } } infoList.add(info); map.put(info.getColNo(), infoList); } //过滤出每列可以用的库位并进行分配 BaseLocationInfo currentLocation = null; for (Map.Entry> entry : map.entrySet()) { List locationInfoList = entry.getValue(); for (BaseLocationLotattVO b : locationInfoList) { //如果允许并行则跳过已经分配过的列 if (locationPriorityHeaderVO.getParallelFlag().equals("Y")) { //如果达到并行数量,则当前区域不再进行分配 if (parallelCount + 1 > locationPriorityHeaderVO.getParallelCount()) { return null; } if (taskingFlag.get(b.getColNo())) { continue; } } // TODO 如果库存中已存在批次属性那么存放相同批次属性的物料 /*if (lotatt.size() > 0) { //指定了批次属性的需要对相同批次属性的库存进行匹配 //如果没有批次属性查询是否有待搬运的属性 if (b.getLotattVO() == null) { LotattVO lotattVO = baseLocationInfoMapper.selectInvLotattById(b.getId()); b.setLotattVO(lotattVO); } b.initLotatt(); boolean isSame = true; for (Map.Entry attEntry : lotatt.entrySet()) { if (!b.getAttMap().get(attEntry.getKey()).equals(attEntry.getValue())) { isSame = false; } } if (isSame == false) { continue; } }*/ if (currentLocation == null) { if (b.getIsEmpty().equals("Y") && b.getStockStatus().equals("00")) { BaseLocationInfo locationInfo = new BaseLocationInfo(); BeanUtils.copyProperties(b, locationInfo); currentLocation = locationInfo; } } else { //如果前面的库位已阻挡则之前的库位不可用 if (!b.getIsEmpty().equals("Y") || !b.getStockStatus().equals("00")) { currentLocation = null; } else { continue; } } } if (currentLocation != null) { break; } } return currentLocation; } /** * 过滤出库 * * @param zoneId * @param outWarehouseDTO * @param locationPriorityHeaderVO * @return */ public BaseLocationInfo filterLockInv(Long zoneId, OutWarehouseDTO outWarehouseDTO, LocationPriorityHeaderVO locationPriorityHeaderVO) { List locationLotattVOList = invLotLocIdMapper.selectInvLocationList(zoneId, outWarehouseDTO.getSku(), outWarehouseDTO.getSkuType(), 0D, "", outWarehouseDTO.getLotattDTO()); List locationPriorityDetails = null; LinkedHashMap lotatt = new LinkedHashMap<>(); if (locationPriorityHeaderVO != null) { locationPriorityDetails = locationPriorityHeaderMapper.selectLocationPriorityDetailsList(locationPriorityHeaderVO.getId()); //批次属性 if (locationPriorityDetails != null && locationPriorityDetails.size() > 0) { for (LocationPriorityDetailsVO vo : locationPriorityDetails) { lotatt.put(vo.getLotattId(), vo.getLotattValue()); } } } //将同一列的库位排序好 Integer parallelCount = 0; LinkedHashMap taskingFlag = new LinkedHashMap<>(); LinkedHashMap> map = new LinkedHashMap<>(); for (BaseLocationLotattVO info : locationLotattVOList) { List infoList; if (map.containsKey(info.getColNo())) { infoList = map.get(info.getColNo()); } else { infoList = new ArrayList<>(); } if (info.getStockStatus().equals("10")) { taskingFlag.put(info.getColNo(), true); parallelCount++; } else { if (taskingFlag.get(info.getColNo()) == null || taskingFlag.get(info.getColNo()).booleanValue() == false) { taskingFlag.put(info.getColNo(), false); } } infoList.add(info); map.put(info.getColNo(), infoList); } //TODO 近效期 //过滤出每列可以用的库位并进行分配 BaseLocationInfo currentLocation = null; for (Map.Entry> entry : map.entrySet()) { List locationInfoList = entry.getValue(); for (BaseLocationLotattVO b : locationInfoList) { if (locationPriorityHeaderVO.getSameLotattFlag().equals("N")) { //如果外围优先则跳过当前出 if (locationPriorityHeaderVO.getOuterFlag().equals("Y")) { if (taskingFlag.get(b.getColNo())) { continue; } } } /*if (locationPriorityHeaderVO.getParallelFlag().equals("Y")) { //如果达到并行数量,则当前区域不再进行分配 if (parallelCount + 1 > locationPriorityHeaderVO.getParallelCount()) { return null; } if (taskingFlag.get(b.getColNo())) { continue; } }*/ if (currentLocation == null) { if (b.getIsEmpty().equals("N") && b.getStockStatus().equals("00")) { BaseLocationInfo locationInfo = new BaseLocationInfo(); BeanUtils.copyProperties(b, locationInfo); currentLocation = locationInfo; } } else { //如果前面的库位已阻挡则之前的库位不可用 if (!b.getIsEmpty().equals("Y") || !b.getStockStatus().equals("00")) { currentLocation = null; } else { continue; } } } if (currentLocation != null) { break; } } return currentLocation; } }