| | |
| | | package com.zy.asrs.service.impl; |
| | | |
| | | import com.alibaba.fastjson.JSON; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.baomidou.mybatisplus.mapper.EntityWrapper; |
| | | import com.baomidou.mybatisplus.mapper.Wrapper; |
| | | import com.core.common.BaseRes; |
| | |
| | | import com.core.common.SnowflakeIdWorker; |
| | | import com.core.exception.CoolException; |
| | | import com.zy.asrs.entity.*; |
| | | import com.zy.asrs.entity.param.EmptyPlateOutParam; |
| | | import com.zy.asrs.entity.param.FullStoreParam; |
| | | import com.zy.asrs.entity.param.LocDetlAdjustParam; |
| | | import com.zy.asrs.entity.param.StockOutParam; |
| | | import com.zy.asrs.entity.param.*; |
| | | import com.zy.asrs.entity.result.WrkCancel; |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.asrs.utils.Utils; |
| | | import com.zy.common.model.*; |
| | |
| | | import com.zy.common.model.enums.WorkNoType; |
| | | import com.zy.common.properties.SlaveProperties; |
| | | import com.zy.common.service.CommonService; |
| | | import com.zy.common.utils.HttpHandler; |
| | | import com.zy.common.web.WcsController; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.text.DateFormat; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | |
| | | private SlaveProperties slaveProperties; |
| | | @Autowired |
| | | private WaitPakinService waitPakinService; |
| | | @Autowired |
| | | private ApiLogService apiLogService; |
| | | @Value("${wcs-slave.cancel}") |
| | | private String cancel; |
| | | @Value("${wcs-slave.url}") |
| | | private String url; |
| | | @Value("${wcs-slave.warehouse}") |
| | | private String warehouse; |
| | | |
| | | @Override |
| | | @Transactional |
| | |
| | | // 检索库位 |
| | | LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo); |
| | | List<String> matnrs = param.getList().stream().map(FullStoreParam.MatCodeStore::getMatnr).distinct().collect(Collectors.toList()); |
| | | List<String> batchs = param.getList().stream().map(FullStoreParam.MatCodeStore::getBatch).distinct().collect(Collectors.toList()); |
| | | StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 1, param.getDevpNo(), matnrs.get(0), batchs.get(0), null,0,locTypeDto,0); |
| | | // List<String> batchs = param.getList().stream().map(FullStoreParam.MatCodeStore::getBatch).distinct().collect(Collectors.toList()); |
| | | StartupDto dto = commonService.getLocNo(1, param.getDevpNo(), matnrs.get(0), null, null,locTypeDto); |
| | | if (Cools.isEmpty(dto)){ |
| | | throw new CoolException("查询库位失败!!==》startupFullPutStore ==》 commonService.getLocNo"); |
| | | } |
| | | // 生成工作号 |
| | | int workNo = dto.getWorkNo(); |
| | | // 生成工作档 |
| | |
| | | } |
| | | } |
| | | if (!locDetlDtos.isEmpty()) { |
| | | LocMast locMast = locMastService.selectOne(new EntityWrapper<LocMast>().eq("loc_no", locDetlDtos.get(0).getLocDetl().getLocNo())); |
| | | if (locMast.getLocSts().equals("F") || locMast.getLocSts().equals("D") ){ |
| | | // 启动出库开始 101.出库 |
| | | stockOut(staNo, locDetlDtos, null, userId); |
| | | }else { |
| | | throw new CoolException("所选库位存在状态不为F、D的库位,库位号:"+locMast.getLocNo()+" 、当前状态:"+locMast.getLocSts()+"-"+locMast.getLocSts$()); |
| | | } |
| | | // 启动出库开始 101.出库 |
| | | stockOut(staNo, locDetlDtos, null, userId); |
| | | } else { |
| | | throw new CoolException("库存不存在"); |
| | | } |
| | |
| | | } |
| | | } |
| | | Integer ioType = null; |
| | | // 生成工作档 |
| | | for (OutLocDto dto : dtos) { |
| | | // 判断入出库类型:101.全板出库 or 103.拣料出库 |
| | | if (ioWorkType == null) { |
| | | ioType = dto.isAll() ? 101 : 103; |
| | | } else if (ioWorkType.equals(IoWorkType.CHECK_OUT)) { |
| | | ioType = 107; |
| | | } |
| | | assert ioType != null; |
| | | // 获取库位 |
| | | LocMast locMast = locMastService.selectById(dto.getLocNo()); |
| | | |
| | | Integer outSta = staNo.getDevNo(); |
| | | // //2号堆垛机全板出库站指定为204站,拣料站指定为202 |
| | | // if(locMast.getCrnNo()==2){ |
| | | // outSta = ioType == 101 ? 204 : 202; |
| | | // } |
| | | // 按列和层分组库位 |
| | | Map<String, List<OutLocDto>> locGroups = dtos.stream() |
| | | .collect(Collectors.groupingBy(dto -> { |
| | | String column = dto.getLocNo().substring(3, 6); // 列号 |
| | | String level = dto.getLocNo().substring(6); // 层号 |
| | | return column + "-" + level; // 组合成唯一的组标识 |
| | | })); |
| | | |
| | | // 获取路径 |
| | | StaDesc staDesc = staDescService.queryCrnStn(ioType, locMast.getCrnNo(), outSta); |
| | | // 生成工作号 |
| | | int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(ioType)); |
| | | // 生成工作档 |
| | | WrkMast wrkMast = new WrkMast(); |
| | | wrkMast.setWrkNo(workNo); |
| | | wrkMast.setIoTime(now); |
| | | wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID |
| | | wrkMast.setIoType(ioType); // 入出库状态 |
| | | wrkMast.setIoPri(13D); // 优先级:13 |
| | | wrkMast.setCrnNo(locMast.getCrnNo()); |
| | | wrkMast.setSourceStaNo(staDesc.getCrnStn()); // 源站 |
| | | wrkMast.setStaNo(staDesc.getStnNo()); // 目标站 |
| | | wrkMast.setSourceLocNo(dto.getLocNo()); // 源库位 |
| | | wrkMast.setFullPlt("Y"); // 满板:Y |
| | | wrkMast.setPicking("N"); // 拣料 |
| | | wrkMast.setExitMk("N"); // 退出 |
| | | wrkMast.setEmptyMk("N"); // 空板 |
| | | wrkMast.setLinkMis("N"); |
| | | wrkMast.setBarcode(locMast.getBarcode()); |
| | | wrkMast.setAppeUser(userId); // 操作人员数据 |
| | | wrkMast.setAppeTime(now); |
| | | wrkMast.setModiUser(userId); |
| | | wrkMast.setModiTime(now); |
| | | if (!wrkMastService.insert(wrkMast)) { |
| | | throw new CoolException("保存工作档失败,出库库位号:"+dto.getLocNo()); |
| | | } |
| | | // 生成工作档明细 |
| | | for (LocDetlDto detlDto : dto.getLocDetlDtos()) { |
| | | if (detlDto.getCount()==null || detlDto.getCount() <= 0.0D) {continue;} |
| | | WrkDetl wrkDetl = new WrkDetl(); |
| | | wrkDetl.sync(detlDto.getLocDetl()); |
| | | wrkDetl.setOrderNo(""); // 手动出库不需要带出库存中的单据编号 |
| | | wrkDetl.setWrkNo(workNo); |
| | | wrkDetl.setIoTime(now); |
| | | Double anfme = ioType==101?detlDto.getLocDetl().getAnfme():detlDto.getCount(); |
| | | wrkDetl.setAnfme(anfme); // 数量 |
| | | wrkDetl.setAppeTime(now); |
| | | wrkDetl.setAppeUser(userId); |
| | | wrkDetl.setModiTime(now); |
| | | wrkDetl.setModiUser(userId); |
| | | if (!wrkDetlService.insert(wrkDetl)) { |
| | | throw new CoolException("保存工作档明细失败"); |
| | | // 遍历每组 |
| | | for (Map.Entry<String, List<OutLocDto>> entry : locGroups.entrySet()) { |
| | | String groupKey = entry.getKey(); // 组标识,例如 "003-02" 表示第3列第2层 |
| | | List<OutLocDto> groupDtos = entry.getValue(); |
| | | |
| | | // 组内优先级重新从100开始 |
| | | double priority = 100; |
| | | |
| | | // 排序组内库位(排号倒序) |
| | | groupDtos.sort(Comparator.comparing((OutLocDto dto) -> Integer.valueOf(dto.getLocNo().substring(0, 2))).reversed()); |
| | | |
| | | for (OutLocDto dto : groupDtos) { |
| | | String locNo = dto.getLocNo(); |
| | | |
| | | // 深库位规则检查,仅检查当前列和层内的前库位 |
| | | int currentRow = Integer.valueOf(locNo.substring(0, 2)); |
| | | for (int i = currentRow + 1; i <= 5; i++) { // 深库位为 1-5 排 |
| | | String frontLoc = String.format("%02d%s", i, locNo.substring(2)); |
| | | LocMast locMastFront = locMastService.selectOne(new EntityWrapper<LocMast>() |
| | | .eq("loc_no", frontLoc).eq("loc_sts", "F")); |
| | | if (!Cools.isEmpty(locMastFront)) { |
| | | throw new CoolException(locNo + " 的前库位 " + frontLoc + " 有货"); |
| | | } |
| | | |
| | | // 判断前库位是否有入库任务 |
| | | WrkMast wrkMastFront = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("loc_no", frontLoc)); |
| | | if (!Cools.isEmpty(wrkMastFront)) { |
| | | throw new CoolException(locNo + " 的前库位 " + frontLoc + " 有入库任务"); |
| | | } |
| | | } |
| | | } |
| | | // 修改库位状态: F.在库 ====>>> R.出库预约/P.拣料/盘点/并板出库中 |
| | | locMast = locMastService.selectById(dto.getLocNo()); |
| | | if (locMast.getLocSts().equals("F")) { |
| | | locMast.setLocSts(ioType==101?"R":"P"); |
| | | locMast.setModiUser(userId); |
| | | locMast.setModiTime(now); |
| | | if (!locMastService.updateById(locMast)) { |
| | | throw new CoolException("预约库位状态失败,库位号:"+dto.getLocNo()); |
| | | |
| | | // 计算优先级 |
| | | dto.setPriority(priority); |
| | | priority--; // 下一个任务优先级递增 |
| | | |
| | | // 获取库位 |
| | | LocMast locMast = locMastService.selectById(dto.getLocNo()); |
| | | if (Cools.isEmpty(locMast)) { |
| | | throw new CoolException(dto.getLocNo() + "库位不存在"); |
| | | } |
| | | } else { |
| | | throw new CoolException(dto.getLocNo() + "库位不是在库状态"); |
| | | if (!locMast.getLocSts().equals("F")) { |
| | | throw new CoolException(dto.getLocNo() + "托盘非在库状态"); |
| | | } |
| | | |
| | | // 判断入出库类型 |
| | | if (ioWorkType == null) { |
| | | ioType = dto.isAll() ? 101 : 103; |
| | | } else if (ioWorkType.equals(IoWorkType.CHECK_OUT)) { |
| | | ioType = 107; |
| | | } |
| | | assert ioType != null; |
| | | |
| | | Integer outSta = staNo.getDevNo(); |
| | | |
| | | // 获取路径 |
| | | StaDesc staDesc = staDescService.queryCrnStn(ioType, locMast.getCrnNo(), outSta); |
| | | |
| | | // 生成工作号 |
| | | int workNo = commonService.getWorkNo(WorkNoType.getWorkNoType(ioType)); |
| | | String pick = ioType == 101 ? "N":"Y"; |
| | | |
| | | // 生成工作档 |
| | | WrkMast wrkMast = new WrkMast(); |
| | | wrkMast.setWrkNo(workNo); |
| | | wrkMast.setIoTime(now); |
| | | wrkMast.setWrkSts(0L); |
| | | wrkMast.setIoType(ioType); |
| | | wrkMast.setIoPri(priority); |
| | | wrkMast.setCrnNo(locMast.getCrnNo()); |
| | | wrkMast.setSourceStaNo(staDesc.getCrnStn()); |
| | | wrkMast.setStaNo(staDesc.getStnNo()); |
| | | wrkMast.setSourceLocNo(dto.getLocNo()); |
| | | wrkMast.setFullPlt("Y"); |
| | | wrkMast.setPicking(pick); |
| | | wrkMast.setExitMk("N"); |
| | | wrkMast.setEmptyMk("N"); |
| | | wrkMast.setLinkMis("N"); |
| | | wrkMast.setBarcode(locMast.getBarcode()); |
| | | wrkMast.setAppeUser(userId); |
| | | wrkMast.setAppeTime(now); |
| | | wrkMast.setModiUser(userId); |
| | | wrkMast.setModiTime(now); |
| | | if (!wrkMastService.insert(wrkMast)) { |
| | | throw new CoolException("保存工作档失败,出库库位号:" + dto.getLocNo()); |
| | | } |
| | | |
| | | // 生成工作档明细 |
| | | for (LocDetlDto detlDto : dto.getLocDetlDtos()) { |
| | | if (detlDto.getCount() == null || detlDto.getCount() <= 0.0D) { |
| | | continue; |
| | | } |
| | | WrkDetl wrkDetl = new WrkDetl(); |
| | | wrkDetl.sync(detlDto.getLocDetl()); |
| | | wrkDetl.setOrderNo(""); |
| | | wrkDetl.setWrkNo(workNo); |
| | | wrkDetl.setIoTime(now); |
| | | Double anfme = ioType == 101 ? detlDto.getLocDetl().getAnfme() : detlDto.getCount(); |
| | | wrkDetl.setAnfme(anfme); |
| | | wrkDetl.setAppeTime(now); |
| | | wrkDetl.setAppeUser(userId); |
| | | wrkDetl.setModiTime(now); |
| | | wrkDetl.setModiUser(userId); |
| | | if (!wrkDetlService.insert(wrkDetl)) { |
| | | throw new CoolException("保存工作档明细失败"); |
| | | } |
| | | } |
| | | |
| | | // 修改库位状态 |
| | | locMast = locMastService.selectById(dto.getLocNo()); |
| | | if (locMast.getLocSts().equals("F")) { |
| | | locMast.setLocSts(ioType == 101 ? "R" : "P"); |
| | | locMast.setModiUser(userId); |
| | | locMast.setModiTime(now); |
| | | if (!locMastService.updateById(locMast)) { |
| | | throw new CoolException("预约库位状态失败,库位号:" + dto.getLocNo()); |
| | | } |
| | | } else { |
| | | throw new CoolException(dto.getLocNo() + "库位不是在库状态"); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); |
| | | // 检索库位 |
| | | LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo); |
| | | StartupDto dto = commonService.getLocNo(DEFAULT_ROW_NO_TYPE, 10, devpNo, null,null,null,0, locTypeDto, 0); |
| | | StartupDto dto = commonService.getLocNo( 10, devpNo, null,null,null, locTypeDto); |
| | | int workNo = dto.getWorkNo(); |
| | | Date now = new Date(); |
| | | // 生成工作档 |
| | |
| | | if (!locMast.getLocSts().equals("D")){ |
| | | throw new CoolException("所选库位存在状态不为D的库位,库位号:"+locMast.getLocNo()+" 、当前状态:"+locMast.getLocSts()+"-"+locMast.getLocSts$()); |
| | | } |
| | | boolean res1 = true; |
| | | if(param.getOutSite()==100){ |
| | | res1 = false; |
| | | } |
| | | List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>() |
| | | .eq("bay1", locMast.getBay1()) |
| | | .eq("lev1",locMast.getLev1()) |
| | | .orderBy("row1",res1)); |
| | | for (LocMast locMast1 : locMasts) { |
| | | if (locMast1.getLocNo().equals(locMast.getLocNo())) { |
| | | break; |
| | | } |
| | | if (locMast1.getLocSts().equals("D") || locMast1.getLocSts().equals("F")) { |
| | | throw new CoolException(locNo+"库位堵塞,禁止出库"); |
| | | } |
| | | } |
| | | // 获取源站 |
| | | Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>() |
| | | .eq("type_no", 110) |
| | |
| | | WrkMast wrkMast = new WrkMast(); |
| | | wrkMast.setWrkNo(workNo); |
| | | wrkMast.setIoTime(now); |
| | | wrkMast.setWrkSts(11L); // 工作状态:11.生成出库ID |
| | | wrkMast.setWrkSts(0L); // 工作状态:0.待发送 |
| | | wrkMast.setIoType(110); // 入出库状态: 110.空板出库 |
| | | wrkMast.setIoPri(10D); |
| | | wrkMast.setSourceStaNo(sourceStaNo); // 源站 |
| | |
| | | if (wrkMast.getWrkSts() == 4 || wrkMast.getWrkSts() == 14) { |
| | | throw new CoolException("当前工作档已完成"); |
| | | } |
| | | // 入库 + 库位转移 |
| | | if (wrkMast.getWrkSts() < 4 || (wrkMast.getWrkSts() > 10 && wrkMast.getIoType()==11)) { |
| | | wrkMast.setWrkSts(4L); |
| | | // 出库 |
| | | } else if (wrkMast.getWrkSts() > 10) { |
| | | if (wrkMast.getIoType() > 100) { |
| | | wrkMast.setWrkSts(14L); |
| | | // 入库 + 库位转移 |
| | | } else if (wrkMast.getIoType()==1 || wrkMast.getIoType()==10 || wrkMast.getIoType()==11) { |
| | | wrkMast.setWrkSts(4L); |
| | | |
| | | } |
| | | Date now = new Date(); |
| | | wrkMast.setCrnStrTime(DateUtils.calculate(now, 1L, TimeUnit.SECONDS, true)); |
| | |
| | | String locNo = ""; // 待修改目标库位 |
| | | String locSts = ""; // 待修改目标库位状态 |
| | | // 入库取消(修改目标库位) |
| | | if (wrkMast.getWrkSts() < 4) { |
| | | if (wrkMast.getIoType() < 100) { |
| | | locNo = wrkMast.getLocNo(); |
| | | locSts = "O"; |
| | | |
| | |
| | | locMastService.updateById(locMast); |
| | | } |
| | | // 出库取消(修改源库位) |
| | | } else if (wrkMast.getWrkSts() > 10 && wrkMast.getWrkSts() != 14) { |
| | | } else if (wrkMast.getIoType() > 100 && wrkMast.getWrkSts() != 14) { |
| | | locNo = wrkMast.getSourceLocNo(); |
| | | // 出库 ===>> F.在库 |
| | | if (wrkMast.getIoType() > 100 && wrkMast.getIoType() != 110) { |
| | | if (wrkMast.getIoType() == 101 || wrkMast.getIoType() == 103) { |
| | | locSts = "F"; |
| | | // 空板出库 ===>> D.空桶/空栈板 |
| | | } else if (wrkMast.getIoType() == 110) { |
| | |
| | | waitPakinService.update(waitPakin, new EntityWrapper<WaitPakin>() |
| | | // .eq("order_no", waitPakin.getOrderNo()) |
| | | .eq("zpallet",waitPakin.getZpallet()) |
| | | .eq("matnr", waitPakin.getMatnr()) |
| | | .eq("batch", waitPakin.getBatch())); |
| | | .eq("matnr", waitPakin.getMatnr())); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (!wrkMastRes || !locMastRes) { |
| | | throw new CoolException("保存数据失败"); |
| | | } |
| | | |
| | | //wms取消任务 同时调用wcs任务取消接口通知wcs |
| | | WrkCancel wrkCancel = new WrkCancel(); |
| | | Date date = new Date(); |
| | | DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); |
| | | wrkCancel.setTaskId(workNo); // 任务号 |
| | | wrkCancel.setMsgTime(dateFormat.format(date)); // 取消时间 |
| | | wrkCancel.setWarehouse(warehouse); // 仓库编码 |
| | | |
| | | String response = ""; |
| | | boolean flag = false; |
| | | try { |
| | | response = new HttpHandler.Builder() |
| | | .setUri(url) |
| | | .setPath(cancel) |
| | | .setJson(JSON.toJSONString(wrkCancel)) |
| | | .build() |
| | | .doPost(); |
| | | JSONObject jsonObject = JSON.parseObject(response); |
| | | if (jsonObject.getInteger("returnStatus") == 0){ |
| | | flag = true; |
| | | }else { |
| | | log.error("wms取消任务下发wcs失败--->url:{};request:{};response:{}", url+"/"+cancel, JSON.toJSONString(wrkCancel), response); |
| | | throw new CoolException("wms取消任务下发wcs失败"); |
| | | } |
| | | }catch (Exception e){ |
| | | log.error("fail", e); |
| | | }finally { |
| | | try { |
| | | //保存接口日志 |
| | | apiLogService.save( |
| | | "wms下发任务给wcs", |
| | | url+"/"+cancel, |
| | | null, |
| | | "127.0.0.1", |
| | | JSON.toJSONString(wrkCancel), |
| | | response, |
| | | flag |
| | | ); |
| | | }catch (Exception e){ |
| | | log.error("",e); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
| | | |
| | | @Override |