package com.vincent.rsf.server.manager.utils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.vincent.rsf.framework.common.Cools; import com.vincent.rsf.framework.common.SpringUtils; import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.api.utils.LocUtils; import com.vincent.rsf.server.manager.controller.dto.ExistDto; import com.vincent.rsf.server.manager.controller.dto.OrderOutItemDto; import com.vincent.rsf.server.manager.controller.params.WaveToLocParams; import com.vincent.rsf.server.manager.entity.*; import com.vincent.rsf.server.manager.enums.TaskType; import com.vincent.rsf.server.manager.enums.WaveRuleType; import com.vincent.rsf.server.manager.service.*; import com.vincent.rsf.server.manager.enums.LocStsType; import org.apache.commons.lang3.StringUtils; import java.math.BigDecimal; import java.util.*; import java.util.stream.Collectors; public class LocManageUtil { /** * @param * @return * @author Ryan * @description 获取目标库位, 包含库位获取策略 * @time 2025/3/31 08:50 */ public static String getTargetLoc(Long areaId) { //TODO 库位策略后续排期 return getTargetLoc(areaId, null); } public static String getTargetLoc(Long areaId, Long containerType,List rowList) { Long locType = containerType; //TODO 库位策略后续排期 LocService locService = SpringUtils.getBean(LocService.class); Loc loc = locService.getOne(new LambdaQueryWrapper() .eq(!Objects.isNull(locType), Loc::getType, locType) .eq(Loc::getAreaId, areaId) .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) .in(Objects.nonNull(rowList) && !rowList.isEmpty(), Loc::getRow, rowList) .orderByAsc(Loc::getLev) .orderByAsc(Loc::getCol) .orderByAsc(Loc::getRow) .last("LIMIT 1") ); return !Objects.isNull(loc) ? loc.getCode() : null; } public static String getTargetLoc(Long areaId, Long containerType) { Long locType = containerType; // if (!Objects.isNull(containerType)) { // LocTypeService locService = SpringUtils.getBean(LocTypeService.class); // if (containerType.equals(ContainerType.CONTAINER_TYPE_NORMAL.val)) { // LocType low = locService.getOne(new LambdaQueryWrapper() // .eq(LocType::getCode, "L")); // if (Objects.isNull(low)) { // throw new CoolException("庫位類型不存在!!"); // } // locType = low.getId(); // } else { // LocType low = locService.getOne(new LambdaQueryWrapper() // .eq(LocType::getCode, "H")); // if (Objects.isNull(low)) { // throw new CoolException("庫位類型不存在!!"); // } // locType = low.getId(); // } // } //TODO 库位策略后续排期 LocService locService = SpringUtils.getBean(LocService.class); Loc loc = locService.getOne(new LambdaQueryWrapper() .eq(!Objects.isNull(locType), Loc::getType, locType) .eq(Loc::getAreaId, areaId) .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) .orderByAsc(Loc::getLev) .orderByAsc(Loc::getCol) .orderByAsc(Loc::getRow) .last("LIMIT 1") ); return !Objects.isNull(loc) ? loc.getCode() : null; } /** * @param * @return * @author Ryan * @description 获取目标站点 * @time 2025/3/31 09:49 */ public static String getTargetSite() { //TODO 站点策略后续排期 DeviceSiteService deviceSite = SpringUtils.getBean(DeviceSiteService.class); DeviceSite loc = deviceSite.getOne(new LambdaQueryWrapper().eq(DeviceSite::getStatus, 1), false); return !Objects.isNull(loc) ? loc.getSite() : null; } /** * 出库策略:--〈效率优化〉 * * @param matnrCode * @param splrBatch * @param anfme * @return */ public static List getEfficiencyFirstItemList(String matnrCode, String splrBatch, Double anfme) { LambdaQueryWrapper locItemQueryWrapper = new LambdaQueryWrapper<>(); locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode); locItemQueryWrapper.eq(StringUtils.isNotBlank(splrBatch), LocItem::getBatch, splrBatch); String applySql = String.format( "EXISTS (SELECT 1 FROM man_loc ml " + "WHERE ml.use_status = '%s'" + "AND ml.id = man_loc_item.loc_id " + ")", LocStsType.LOC_STS_TYPE_F.type ); locItemQueryWrapper.apply(applySql); LocItemService locItemService = SpringUtils.getBean(LocItemService.class); List locItems = locItemService.list(locItemQueryWrapper); locItems.sort(Comparator.comparing((LocItem item) -> !LocUtils.isShallowLoc(item.getLocCode()))); List locsSet = locItems.stream().filter(locItem -> locItem.getAnfme().compareTo(anfme) == 0.0).collect(Collectors.toList()); if (!locsSet.isEmpty()) { return locsSet; } return locItems; } /** * 出库策略:--<先进先出> * * @param matnrCode * @param splrBatch * @param anfme * @return */ public static List getFirstInFirstOutItemList(String matnrCode, String splrBatch, Double anfme) { LambdaQueryWrapper locItemQueryWrapper = new LambdaQueryWrapper<>(); locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode); locItemQueryWrapper.eq(StringUtils.isNotEmpty(splrBatch), LocItem::getBatch, splrBatch); //如果批次不为空,按批次先后出库 if (StringUtils.isNotBlank(splrBatch)) { locItemQueryWrapper.orderByAsc(LocItem::getBatch); } else { locItemQueryWrapper.orderByAsc(LocItem::getCreateTime); } String applySql = String.format( "EXISTS (SELECT 1 FROM man_loc ml " + "WHERE ml.use_status = '%s'" + "AND ml.id = man_loc_item.loc_id " + ")", LocStsType.LOC_STS_TYPE_F.type ); locItemQueryWrapper.apply(applySql); LocItemService locItemService = SpringUtils.getBean(LocItemService.class); List locItems = locItemService.list(locItemQueryWrapper); return locItems; } /** * 获取出库库位信息 * * @param params * @param waveRule * @return */ public static List getOutOrderList(List params, WaveRule waveRule) { LocService locService = SpringUtils.getBean(LocService.class); LocItemService locItemService = SpringUtils.getBean(LocItemService.class); DeviceSiteService deviceSiteService = SpringUtils.getBean(DeviceSiteService.class); BasStationAreaService basStationAreaService = SpringUtils.getBean(BasStationAreaService.class); // List basStationAreas = basStationAreaService.list(new LambdaQueryWrapper<>());// List locList = new ArrayList<>(); List list = new ArrayList<>(); //不让站点重复使用问题 List stations = new ArrayList<>(); Set existDtos = new HashSet<>(); for (WaveToLocParams item : params) { BigDecimal issued = new BigDecimal(item.getAnfme().toString()) .subtract(new BigDecimal(item.getWorkQty().toString())); if (issued.doubleValue() <= 0) { continue; } List locItems; if (Objects.isNull(waveRule)) { locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme()); } else { if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) { locItems = LocManageUtil.getEfficiencyFirstItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme()); } else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) { locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme()); } else { locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme()); } } for (LocItem locItem : locItems) { Loc loc = locService.getById(locItem.getLocId()); List itemList = locItemService.list(new LambdaQueryWrapper().eq(LocItem::getLocId, loc.getId())); if (issued.doubleValue() > 0 && locList.contains(loc)) { for (OrderOutItemDto itemDto : list) { if (itemDto.getLoc().equals(loc)) { ExistDto existDto = new ExistDto().setBatch(locItem.getBatch()).setMatnr(locItem.getMatnrCode()).setLocNo(locItem.getLocCode()); if (existDtos.add(existDto)) { locItem.setOutQty(issued.doubleValue() >= locItem.getAnfme() ? locItem.getAnfme() : issued.doubleValue()); locItem.setBarcode(loc.getBarcode()) .setSourceId(item.getWaveId())//波次ID .setSource(item.getItemId());//波次明细ID itemDto.getLocItemList().add(locItem); issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString())); } break; } } } else if (issued.doubleValue() > 0) { ExistDto existDto = new ExistDto().setBatch(locItem.getBatch()).setMatnr(locItem.getMatnrCode()).setLocNo(locItem.getLocCode()); if (existDtos.add(existDto)) { locItem.setOutQty(issued.doubleValue() >= locItem.getAnfme() ? locItem.getAnfme() : issued.doubleValue()); locItem.setBarcode(loc.getBarcode()) .setSourceId(item.getWaveId())//波次ID .setSource(item.getItemId());//波次明细ID OrderOutItemDto orderOutItemDto = new OrderOutItemDto(); // orderOutItemDto.setLocItem(locItem); orderOutItemDto.setLoc(loc); orderOutItemDto.getLocItemList().add(locItem); BasContainer containerType = getContainerType(loc.getBarcode()); List basStationAreas = basStationAreaService.list(new LambdaQueryWrapper() .apply("JSON_CONTAINS(cross_zone_area, '{0}') = 1", loc.getAreaId())//可执行库区区区域id .apply("JSON_CONTAINS(container_type, '{0}') = 1", containerType)//容器类型 // .apply("JSON_CONTAINS(station_alias, '\"{0}\"') = 1", null)//区域包含站点集 .eq(BasStationArea::getDeleted, 0));// 通常需要加上未删除条件 List targSiteAreaList = new ArrayList<>(); for (BasStationArea basStationArea : basStationAreas) { targSiteAreaList.add(basStationArea.getStationAreaId()); } int count = 0; for (BasStationArea basStationArea : basStationAreas) { count++; if (!basStationArea.getStationAlias().isEmpty()) { List maps = new ArrayList<>(); for (String site : basStationArea.getStationAlias()) { OrderOutItemDto.staListDto staListDto = new OrderOutItemDto.staListDto(); staListDto.setStaNo(site); staListDto.setStaName(site); maps.add(staListDto); } orderOutItemDto.setStaNos(maps); //获取满足条件站点 Set stationSet = new HashSet<>(basStationArea.getStationAlias()); // Set stationSet = basStationArea.getStationAlias().stream().collect(Collectors.toSet()); // Set stationSet = deviceSites.stream().map(DeviceSite::getSite).collect(Collectors.toSet()); //已使用站点 Set stas = stations.stream().map(BasStation::getStationName).collect(Collectors.toSet()); BasStationService basStationService = SpringUtils.getBean(BasStationService.class); BasStation basStation = basStationService.getOne(new LambdaQueryWrapper() .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type) .in(BasStation::getStationName, stationSet) .notIn(!stas.isEmpty(), BasStation::getStationName, stas) .last("LIMIT 1")); if (!Objects.isNull(basStation)) { stations.add(basStation); } if (count == basStationAreas.size()) { if (!Objects.isNull(basStation)) { orderOutItemDto.setSiteNo(basStation.getStationName()); // throw new CoolException("站點不存在!!"); } } else { if (Objects.isNull(basStation)) { continue; // throw new CoolException("站點不存在!!"); } orderOutItemDto.setSiteNo(basStation.getStationName()); } } orderOutItemDto.setSource(item.getItemId().toString()) .setTargSiteAreaList(targSiteAreaList) .setSourceId(item.getWaveId().toString()); list.add(orderOutItemDto); locList.add(loc); issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString())); break; } } } } } return list; } //根据条码获取规则 private static BasContainer getContainerType(String barcode) { BasContainerService basContainerService = SpringUtils.getBean(BasContainerService.class); if (Cools.isEmpty(barcode)) { throw new CoolException("容器码不能为空"); } List containers = basContainerService.list(new LambdaQueryWrapper<>()); for (BasContainer container : containers) { String codeType = container.getCodeType(); // 获取正则表达式 if (barcode.matches(codeType)) { // 判断条码是否符合这个正则 return container; } } return null; } }