| | |
| | | import com.core.exception.CoolException; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.entity.param.*; |
| | | import com.zy.asrs.entity.result.FindLocNoAttributeVo; |
| | | import com.zy.asrs.entity.result.ForwardAGVTaskDTO; |
| | | import com.zy.asrs.entity.result.HIKApiDTO; |
| | | import com.zy.asrs.entity.result.HIKResultDTO; |
| | | import com.zy.asrs.enums.*; |
| | | import com.zy.asrs.enums.OrderSettle; |
| | | import com.zy.asrs.enums.LocAreaType; |
| | | import com.zy.asrs.enums.LocStsType; |
| | | import com.zy.asrs.mapper.LocMastMapper; |
| | |
| | | import com.zy.common.constant.MesConstant; |
| | | import com.zy.common.entity.Parameter; |
| | | import com.zy.common.model.DetlDto; |
| | | import com.zy.common.model.LocDetlDto; |
| | | import com.zy.common.model.LocTypeDto; |
| | | import com.zy.common.model.MesCombParam; |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.model.enums.IoWorkType; |
| | | import com.zy.common.model.enums.WorkNoType; |
| | | import com.zy.common.service.CommonService; |
| | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | import java.util.*; |
| | | import java.util.concurrent.atomic.AtomicReference; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | |
| | | private BasAreasService basAreasService; |
| | | @Autowired |
| | | private StationRelaService stationRelaService; |
| | | @Autowired |
| | | private BasStationDetlService basStationDetlService; |
| | | |
| | | @Override |
| | | @Transactional |
| | |
| | | |
| | | /** |
| | | * 缓存出库组托上架 |
| | | * @author Ryan |
| | | * @date 2025/12/8 13:47 |
| | | * |
| | | * @param params |
| | | * @return com.core.common.R |
| | | * @author Ryan |
| | | * @date 2025/12/8 13:47 |
| | | */ |
| | | @Override |
| | | public R combOutPub(AgvCallParams params) { |
| | |
| | | |
| | | /** |
| | | * 缓存组托数据 |
| | | * @author Ryan |
| | | * @date 2025/12/8 15:37 |
| | | * |
| | | * @param params |
| | | * @return com.core.common.R |
| | | * @author Ryan |
| | | * @date 2025/12/8 15:37 |
| | | */ |
| | | @Override |
| | | public R combCacehList(AgvCallParams params) { |
| | |
| | | } |
| | | |
| | | /** |
| | | * 缓存区上架组托 |
| | | * |
| | | * @param param |
| | | * @param userId |
| | | * @author Ryan |
| | | * @date 2025/12/9 13:45 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void cacheComb(CombParam param, Long userId) { |
| | | if (Objects.isNull(param.getBarcode())) { |
| | | throw new CoolException("托盘码不能为空!!"); |
| | | } |
| | | if (Objects.isNull(param.getCombMats()) || param.getCombMats().isEmpty()) { |
| | | throw new CoolException("组托明细不能为空!!"); |
| | | } |
| | | // 判断是否有相同条码的数据 |
| | | if (waitPakinService.selectCount(new EntityWrapper<WaitPakin>(). |
| | | eq("zpallet", param.getBarcode()) |
| | | .eq("io_status", "N")) > 0) { |
| | | throw new CoolException(param.getBarcode() + "数据正在进行入库"); |
| | | } |
| | | |
| | | int countLoc = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet", param.getBarcode())); |
| | | int countWrk = wrkDetlService.selectCount(new EntityWrapper<WrkDetl>().eq("zpallet", param.getBarcode())); |
| | | int countwait = waitPakinService.selectCount(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode())); |
| | | if (countLoc > 0 || countWrk > 0 || countwait > 0) { |
| | | throw new CoolException("组托档/工作档/库存条码数据已存在===>>" + param.getBarcode()); |
| | | } |
| | | |
| | | // 生成入库通知档 |
| | | List<DetlDto> detlDtos = new ArrayList<>(); |
| | | param.getCombMats().forEach(elem -> { |
| | | DetlDto detlDto = new DetlDto(elem.getMatnr(), elem.getBatch(), elem.getBrand(), elem.getStandby1(), elem.getStandby2(), elem.getStandby3(), |
| | | elem.getBoxType1(), elem.getBoxType2(), elem.getBoxType3(), elem.getAnfme(), elem.getThreeCode()); |
| | | if (DetlDto.has(detlDtos, detlDto)) { |
| | | DetlDto one = DetlDto.findDto(detlDtos, detlDto); |
| | | assert one != null; |
| | | one.setAnfme(one.getAnfme() + detlDto.getAnfme()); |
| | | } else { |
| | | detlDtos.add(detlDto); |
| | | } |
| | | }); |
| | | |
| | | Date now = new Date(); |
| | | for (DetlDto detlDto : detlDtos) { |
| | | Mat mat = matService.selectByMatnr(detlDto.getMatnr()); |
| | | if (Cools.isEmpty(mat)) { |
| | | throw new CoolException(detlDto.getMatnr() + "商品档案不存在"); |
| | | } |
| | | if (mat.getUpQty().compareTo(detlDto.getAnfme()) < 0) { |
| | | throw new CoolException("物料:" + detlDto.getMatnr() + "单次最大组托上限为:" + mat.getUpQty()); |
| | | } |
| | | WaitPakin waitPakin = new WaitPakin(); |
| | | BeanUtils.copyProperties(mat, waitPakin); |
| | | waitPakin.setBatch(detlDto.getBatch()); |
| | | waitPakin.setZpallet(param.getBarcode()); |
| | | //设置组托类型 |
| | | waitPakin.setType(CommonEnum.COMMON_ENUM_Y.type + ""); |
| | | waitPakin.setIoStatus("N"); |
| | | waitPakin.setAnfme(detlDto.getAnfme()); |
| | | waitPakin.setThreeCode(detlDto.getThreeCode()); |
| | | waitPakin.setStatus("Y"); |
| | | waitPakin.setStandby1(detlDto.getStandby1()); |
| | | waitPakin.setStandby2(detlDto.getStandby2()); |
| | | waitPakin.setStandby3(detlDto.getStandby3()); |
| | | waitPakin.setBoxType1(detlDto.getBoxType1()); |
| | | waitPakin.setBoxType2(detlDto.getBoxType2()); |
| | | waitPakin.setBoxType3(detlDto.getBoxType3()); |
| | | waitPakin.setAppeUser(userId); |
| | | waitPakin.setAppeTime(now); |
| | | waitPakin.setModiUser(userId); |
| | | waitPakin.setModiTime(now); |
| | | if (!waitPakinService.insert(waitPakin)) { |
| | | throw new CoolException("保存入库通知档失败"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 缓存入库上架 |
| | | * |
| | | * @param param |
| | | * @param userId |
| | | * @author Ryan |
| | | * @date 2025/12/9 15:05 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void combInPub(CompleteParam param, Long userId) { |
| | | if (Objects.isNull(param.getBarcode())) { |
| | | throw new CoolException("托盘码不能为空!!"); |
| | | } |
| | | if (Objects.isNull(param.getStation())) { |
| | | throw new CoolException("站点不能为空!!"); |
| | | } |
| | | //TODO 修改缓存站点状态及数据 |
| | | Task task = taskService.selectOne(new EntityWrapper<Task>().eq("barcode", param.getBarcode())); |
| | | if (Objects.isNull(task)) { |
| | | throw new CoolException("数据错误,任务不存在!!"); |
| | | } |
| | | List<TaskDetl> taskDetls = taskDetlService.selectList(new EntityWrapper<TaskDetl>().eq("wrk_no", task.getWrkNo())); |
| | | if (Objects.isNull(taskDetls) || taskDetls.isEmpty()) { |
| | | throw new CoolException("数据错误,任务明细不存在!!"); |
| | | } |
| | | |
| | | BasStation station = basStationService.selectOne(new EntityWrapper<BasStation>() |
| | | .eq("dev_no", task.getStaNo())); |
| | | if (Objects.isNull(station)) { |
| | | throw new CoolException("站点不存在!!"); |
| | | } |
| | | |
| | | station.setLocSts(LocStsType.LOC_STS_TYPE_O.type); |
| | | if (!basStationService.updateById(station)) { |
| | | throw new CoolException("站点状态修改失败!"); |
| | | } |
| | | |
| | | if (!basStationDetlService.delete(new EntityWrapper<BasStationDetl>().eq("dev_no", station.getDevNo()))) { |
| | | throw new CoolException("站点删除失败!"); |
| | | } |
| | | |
| | | //任务完成 |
| | | task.setWrkSts(15L); |
| | | |
| | | if (!taskService.updateById(task)) { |
| | | throw new CoolException("AGV任务完成失败!!"); |
| | | } |
| | | |
| | | List<WaitPakin> waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("barcodee", param.getBarcode())); |
| | | if (Objects.isNull(waitPakins) || waitPakins.isEmpty()) { |
| | | throw new CoolException("数据错误,组拖档已不存在!!"); |
| | | } |
| | | |
| | | generateCrnInTask(waitPakins, station, param.getLocType1(), userId); |
| | | } |
| | | |
| | | /** |
| | | * 生成堆垛机入库任务 |
| | | * |
| | | * @param station |
| | | * @author Ryan |
| | | * @date 2025/12/9 13:54 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void generateCrnInTask(List<WaitPakin> waitPakins, BasStation station, Short locType, Long userId) { |
| | | Date now = new Date(); |
| | | StationRela rela = stationRelaService.selectOne(new EntityWrapper<StationRela>() |
| | | .eq("dev_no", station.getDevNo()) |
| | | .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); |
| | | |
| | | if (Objects.isNull(rela)) { |
| | | throw new CoolException("未绑定作业站点!!"); |
| | | } |
| | | |
| | | BasDevp sourceStaNo = basDevpService.checkSiteStatus(Integer.parseInt(rela.getCrnSta()), true); |
| | | |
| | | sourceStaNo.setLocType1(locType); |
| | | LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo); |
| | | WaitPakin pakin = waitPakins.stream().findFirst().get(); |
| | | FindLocNoAttributeVo findLocNoAttributeVo = new FindLocNoAttributeVo(pakin); |
| | | StartupDto dto = commonService.getLocNo( 1, sourceStaNo.getDevNo(),findLocNoAttributeVo, locTypeDto); |
| | | int workNo = dto.getWorkNo(); |
| | | // 生成工作档 |
| | | WrkMast wrkMast = new WrkMast(); |
| | | wrkMast.setWrkNo(workNo); |
| | | wrkMast.setIoTime(new Date()); |
| | | wrkMast.setWrkSts(2L); // 工作状态:生成入库ID |
| | | wrkMast.setIoType(1); // 入出库状态:1.入库 |
| | | wrkMast.setIoPri(13D); // 优先级 |
| | | wrkMast.setCrnNo(dto.getCrnNo()); |
| | | wrkMast.setSourceStaNo(dto.getSourceStaNo() + ""); |
| | | wrkMast.setStaNo(dto.getStaNo() + ""); |
| | | wrkMast.setLocNo(dto.getLocNo()); |
| | | wrkMast.setBarcode(pakin.getBarcode()); // 托盘码 |
| | | wrkMast.setFullPlt("Y"); // 满板:Y |
| | | wrkMast.setPicking("N"); // 拣料 |
| | | wrkMast.setExitMk("N"); // 退出 |
| | | wrkMast.setEmptyMk("N"); // 空板 |
| | | wrkMast.setLinkMis("Y"); |
| | | wrkMast.setModiUser(userId); |
| | | wrkMast.setAppeUser(userId); |
| | | wrkMast.setCtnType(sourceStaNo.getCtnType()); // 容器类型 |
| | | // 操作人员数据 |
| | | wrkMast.setAppeTime(now); |
| | | wrkMast.setModiTime(now); |
| | | boolean res = wrkMastService.insert(wrkMast); |
| | | if (!res) { |
| | | throw new CoolException("保存工作档失败"); |
| | | } |
| | | // 生成工作档明细 |
| | | waitPakins.forEach(waitPakin -> { |
| | | WrkDetl wrkDetl = new WrkDetl(); |
| | | wrkDetl.sync(waitPakin); |
| | | wrkDetl.setWrkNo(wrkMast.getWrkNo()); |
| | | wrkDetl.setIoTime(wrkMast.getIoTime()); |
| | | wrkDetl.setAppeTime(now); |
| | | wrkDetl.setModiTime(now); |
| | | if (!wrkDetlService.insert(wrkDetl)) { |
| | | throw new CoolException("保存工作明细失败"); |
| | | } |
| | | }); |
| | | // 更新入库通知档 ioStatus ===>> Y |
| | | Wrapper<WaitPakin> wrapper = new EntityWrapper<WaitPakin>() |
| | | .eq("zpallet", pakin.getBarcode()); |
| | | WaitPakin setParam = new WaitPakin(); |
| | | setParam.setLocNo(dto.getLocNo()); |
| | | setParam.setIoStatus("Y"); |
| | | setParam.setModiTime(now); |
| | | if (!waitPakinService.update(setParam, wrapper)) { |
| | | throw new CoolException("更新通知档失败"); |
| | | } |
| | | // 更新源站点信息 |
| | | sourceStaNo.setWrkNo(workNo); |
| | | sourceStaNo.setModiTime(now); |
| | | if (!basDevpService.updateById(sourceStaNo)){ |
| | | throw new CoolException("更新源站失败"); |
| | | } |
| | | // 更新目标库位状态 |
| | | LocMast locMast = locMastService.selectById(dto.getLocNo()); |
| | | if (locMast.getLocSts().equals("O")){ |
| | | locMast.setLocSts("S"); // S.入库预约 |
| | | locMast.setModiTime(now); |
| | | if (!locMastService.updateById(locMast)){ |
| | | throw new CoolException("改变库位状态失败"); |
| | | } |
| | | } else { |
| | | throw new CoolException(dto.getLocNo()+"目标库位已被占用"); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 生成立库出库任务 |
| | | * 台车过来默认是同一种物料类型 |
| | | * |
| | | * @param locCaches |
| | | * @author Ryan |
| | |
| | | List<LocDetl> locDetls = locDetlService.selectList(new EntityWrapper<LocDetl>() |
| | | .eq("area_id", basAreas.getId()) |
| | | .eq("loc_id", locCaches.getId())); |
| | | if (Objects.isNull(locDetls)) { |
| | | if (Objects.isNull(locDetls) || locDetls.isEmpty()) { |
| | | throw new CoolException("库存明细不存在!!"); |
| | | } |
| | | |
| | | Set<String> set = locDetls.stream().map(LocDetl::getMatnr).collect(Collectors.toSet()); |
| | | List<Mat> matList = matService.selectList(new EntityWrapper<Mat>().in("matnr", set)); |
| | | if (Objects.isNull(matList) || matList.isEmpty()) { |
| | | throw new CoolException("物料库不存在该物料!!"); |
| | | } |
| | | Set<Long> longs = matList.stream().map(Mat::getTagId).collect(Collectors.toSet()); |
| | | if (!longs.isEmpty() && longs.size() > 1) { |
| | | throw new CoolException("物料类型不一致,请检查数据是否正确!!"); |
| | | } |
| | | |
| | | //获取立库区信息 |
| | | BasAreas one = basAreasService.selectOne(new EntityWrapper<BasAreas>().eq("whs_type_id", LocAreaType.LOC_AREA_TYPE_CRN.type)); |
| | | if (Objects.isNull(one)) { |
| | |
| | | } |
| | | Collections.shuffle(devps); |
| | | BasDevp basDevp = devps.stream().findFirst().get(); |
| | | |
| | | List<LocMast> locMasts = new ArrayList<>(); |
| | | Map<String, List<LocDetl>> listMap = locDetls.stream().collect(Collectors.groupingBy(LocDetl::getMatnr)); |
| | | AtomicReference<Double> totalOut = new AtomicReference<>(locDetls.stream().mapToDouble(LocDetl::getAnfme).sum()); |
| | | listMap.forEach((matnr, detls) -> { |
| | | //根据supId(供应商)分类,得到出库总数 |
| | | Map<String, List<LocDetl>> supIds = detls.stream().collect(Collectors.groupingBy(LocDetl::getStandby1)); |
| | |
| | | if (sum.compareTo(v) <= 0) { |
| | | //可放下 |
| | | locMasts.add(locMast); |
| | | totalOut.set(Math.round((totalOut.get() - sum) * 10000) / 10000.0); |
| | | } |
| | | } |
| | | }); |
| | |
| | | }); |
| | | }); |
| | | |
| | | //判断根据分拣出库后,还需要出多少托盘或料箱;如果余料大于0, 出新托盘或料箱 |
| | | if (totalOut.get().compareTo(0.0) > 0) { |
| | | // Set<String> matnrs = locDetls.stream().map(LocDetl::getMatnr).collect(Collectors.toSet()); |
| | | // List<Mat> mats = matService.selectList(new EntityWrapper<Mat>().in("matnr", matnrs)); |
| | | LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>() |
| | | //todo 根据物料种类,区分库区类型 |
| | | .eq("loc_sts", LocStsType.LOC_STS_TYPE_D.type) |
| | | .orderAsc(Arrays.asList("row1", "bay1", "lev1")) |
| | | .last("OFFSET 0 ROWS FETCH NEXT 1 ROWS ONLY")); |
| | | locMasts.add(locMast); |
| | | |
| | | //空板出库 |
| | | generateTask(locMasts, TaskIOType.EMPTY_OUT.type, basDevp, userId); |
| | | |
| | | } else { |
| | | if (!locMasts.isEmpty()) { |
| | | //生成堆垛机出库任务 |
| | | generateOutTask(locMasts, TaskIOType.MERGE_OUT.type, basDevp, userId); |
| | | generateTask(locMasts, TaskIOType.MERGE_OUT.type, basDevp, userId); |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 生成堆垛机出库任务 |
| | |
| | | * @date 2025/12/6 14:44 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public void generateOutTask(List<LocMast> locMasts, Integer ioType, BasDevp devp, Long userId) { |
| | | public void generateTask(List<LocMast> locMasts, Integer ioType, BasDevp devp, Long userId) { |
| | | Date now = new Date(); |
| | | for (LocMast locMast : locMasts) { |
| | | if (Objects.isNull(ioType)) { |