| | |
| | | import com.core.common.Cools; |
| | | import com.core.common.R; |
| | | import com.core.exception.CoolException; |
| | | import com.zy.api.controller.params.ReassignLocParams; |
| | | import com.zy.api.controller.params.ReceviceTaskParams; |
| | | import com.zy.api.controller.params.StopOutTaskParams; |
| | | import com.zy.api.controller.params.WorkTaskParams; |
| | |
| | | import com.zy.asrs.service.*; |
| | | import com.zy.asrs.utils.Utils; |
| | | import com.zy.common.constant.MesConstant; |
| | | import com.zy.common.model.LocTypeDto; |
| | | import com.zy.common.model.StartupDto; |
| | | import com.zy.common.service.CommonService; |
| | | import com.zy.common.utils.HttpHandler; |
| | | import lombok.extern.slf4j.Slf4j; |
| | |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.io.IOException; |
| | | import java.math.BigDecimal; |
| | | import java.util.*; |
| | | import java.util.concurrent.TimeUnit; |
| | | import java.util.stream.Collectors; |
| | |
| | | private BasCrnpService basCrnpService; |
| | | @Autowired |
| | | private ApiLogService apiLogService; |
| | | @Autowired |
| | | private RowLastnoService rowLastnoService; |
| | | |
| | | |
| | | /** |
| | |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R reassignInboundLoc(ReassignLocParams params) { |
| | | if (params == null) { |
| | | return R.error("参数不能为空!!"); |
| | | } |
| | | if (Cools.isEmpty(params.getTaskNo())) { |
| | | return R.error("任务号不能为空!!"); |
| | | } |
| | | |
| | | WrkMast wrkMast = wrkMastService.selectOne(new EntityWrapper<WrkMast>().eq("wrk_no", params.getTaskNo())); |
| | | String validateMsg = validateReassignInboundTask(wrkMast); |
| | | if (!Cools.isEmpty(validateMsg)) { |
| | | return R.error(validateMsg); |
| | | } |
| | | |
| | | LocMast currentLoc = locMastService.selectById(wrkMast.getLocNo()); |
| | | if (Cools.isEmpty(currentLoc)) { |
| | | return R.error("当前目标库位不存在"); |
| | | } |
| | | |
| | | Integer preferredArea = resolveReassignArea(wrkMast, currentLoc); |
| | | if (preferredArea == null) { |
| | | return R.error("无法确定任务所属库区"); |
| | | } |
| | | |
| | | List<Integer> candidateCrnNos = buildReassignCandidateCrnNos(preferredArea, wrkMast.getCrnNo()); |
| | | if (candidateCrnNos.isEmpty()) { |
| | | return R.error("当前库区没有其他堆垛机可供重分配"); |
| | | } |
| | | |
| | | LocTypeDto locTypeDto = buildReassignLocTypeDto(currentLoc); |
| | | StartupDto startupDto = commonService.findRun2InboundLocByCandidateCrnNos( |
| | | wrkMast.getSourceStaNo(), wrkMast.getIoType(), preferredArea, candidateCrnNos, locTypeDto); |
| | | if (startupDto == null || Cools.isEmpty(startupDto.getLocNo())) { |
| | | return R.error("当前库区没有可重新分配的空库位"); |
| | | } |
| | | |
| | | LocMast targetLoc = locMastService.selectById(startupDto.getLocNo()); |
| | | if (Cools.isEmpty(targetLoc)) { |
| | | throw new CoolException("新目标库位不存在"); |
| | | } |
| | | if (!"O".equals(targetLoc.getLocSts())) { |
| | | throw new CoolException(targetLoc.getLocNo() + "目标库位已被占用"); |
| | | } |
| | | |
| | | Date now = new Date(); |
| | | updateReassignTargetLoc(targetLoc, wrkMast, currentLoc, now); |
| | | updateReassignWorkMast(wrkMast, startupDto, now); |
| | | releaseOldReservedLocIfNeeded(currentLoc, targetLoc.getLocNo(), now); |
| | | |
| | | Map<String, Object> result = new LinkedHashMap<>(); |
| | | result.put("locNo", Utils.WMSLocToWCSLoc(targetLoc.getLocNo())); |
| | | return R.ok("操作成功").add(result); |
| | | } |
| | | |
| | | private boolean requiresOutboundErpConfirm(WrkMast wrkMast) { |
| | | Integer ioType = wrkMast == null ? null : wrkMast.getIoType(); |
| | | return ioType != null && (ioType == 101 || ioType == 103 || ioType == 104 || ioType == 107 || ioType == 110); |
| | |
| | | return null; |
| | | } |
| | | |
| | | private String validateReassignInboundTask(WrkMast wrkMast) { |
| | | if (wrkMast == null) { |
| | | return "任务不存在"; |
| | | } |
| | | if (wrkMast.getIoType() == null || (wrkMast.getIoType() != 1 && wrkMast.getIoType() != 10)) { |
| | | return "当前任务不是入库任务"; |
| | | } |
| | | if (!Objects.equals(wrkMast.getWrkSts(), 2L)) { |
| | | return "当前任务状态不允许重新分配入库位"; |
| | | } |
| | | if (wrkMast.getCrnNo() == null) { |
| | | return "当前任务未分配堆垛机"; |
| | | } |
| | | if (Cools.isEmpty(wrkMast.getLocNo())) { |
| | | return "当前任务未分配目标库位"; |
| | | } |
| | | if (wrkMast.getSourceStaNo() == null) { |
| | | return "当前任务缺少源站信息"; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private Integer resolveReassignArea(WrkMast wrkMast, LocMast currentLoc) { |
| | | Integer stationArea = Utils.getStationStorageArea(wrkMast.getSourceStaNo()); |
| | | if (belongsToArea(stationArea, wrkMast.getCrnNo(), currentLoc)) { |
| | | return stationArea; |
| | | } |
| | | Integer fallbackArea = findAreaByCurrentTask(wrkMast.getCrnNo(), currentLoc); |
| | | if (fallbackArea != null) { |
| | | return fallbackArea; |
| | | } |
| | | return stationArea; |
| | | } |
| | | |
| | | private Integer findAreaByCurrentTask(Integer currentCrnNo, LocMast currentLoc) { |
| | | for (int area = 1; area <= 3; area++) { |
| | | if (belongsToArea(area, currentCrnNo, currentLoc)) { |
| | | return area; |
| | | } |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private boolean belongsToArea(Integer area, Integer currentCrnNo, LocMast currentLoc) { |
| | | if (area == null || area <= 0) { |
| | | return false; |
| | | } |
| | | RowLastno areaRowLastno = rowLastnoService.selectById(area); |
| | | if (areaRowLastno == null) { |
| | | return false; |
| | | } |
| | | Integer startCrnNo = resolveAreaStartCrnNo(areaRowLastno); |
| | | Integer endCrnNo = resolveAreaEndCrnNo(areaRowLastno, startCrnNo); |
| | | if (currentCrnNo != null && currentCrnNo >= startCrnNo && currentCrnNo <= endCrnNo) { |
| | | return true; |
| | | } |
| | | Integer row = currentLoc == null ? null : currentLoc.getRow1(); |
| | | Integer startRow = areaRowLastno.getsRow(); |
| | | Integer endRow = areaRowLastno.geteRow(); |
| | | return row != null && startRow != null && endRow != null && row >= startRow && row <= endRow; |
| | | } |
| | | |
| | | private List<Integer> buildReassignCandidateCrnNos(Integer area, Integer currentCrnNo) { |
| | | RowLastno areaRowLastno = rowLastnoService.selectById(area); |
| | | if (areaRowLastno == null) { |
| | | throw new CoolException("未找到库区轮询规则"); |
| | | } |
| | | int startCrnNo = resolveAreaStartCrnNo(areaRowLastno); |
| | | int endCrnNo = resolveAreaEndCrnNo(areaRowLastno, startCrnNo); |
| | | if (currentCrnNo == null || currentCrnNo < startCrnNo || currentCrnNo > endCrnNo) { |
| | | throw new CoolException("当前任务堆垛机不在所属库区范围内"); |
| | | } |
| | | List<Integer> candidateCrnNos = new ArrayList<>(); |
| | | for (int crnNo = currentCrnNo - 1; crnNo >= startCrnNo; crnNo--) { |
| | | candidateCrnNos.add(crnNo); |
| | | } |
| | | for (int crnNo = endCrnNo; crnNo > currentCrnNo; crnNo--) { |
| | | candidateCrnNos.add(crnNo); |
| | | } |
| | | return candidateCrnNos; |
| | | } |
| | | |
| | | private int resolveAreaStartCrnNo(RowLastno areaRowLastno) { |
| | | if (areaRowLastno.getsCrnNo() != null && areaRowLastno.getsCrnNo() > 0) { |
| | | return areaRowLastno.getsCrnNo(); |
| | | } |
| | | return 1; |
| | | } |
| | | |
| | | private int resolveAreaEndCrnNo(RowLastno areaRowLastno, int startCrnNo) { |
| | | if (areaRowLastno.geteCrnNo() != null && areaRowLastno.geteCrnNo() >= startCrnNo) { |
| | | return areaRowLastno.geteCrnNo(); |
| | | } |
| | | int crnQty = areaRowLastno.getCrnQty() == null || areaRowLastno.getCrnQty() <= 0 ? 1 : areaRowLastno.getCrnQty(); |
| | | return startCrnNo + crnQty - 1; |
| | | } |
| | | |
| | | private LocTypeDto buildReassignLocTypeDto(LocMast currentLoc) { |
| | | LocTypeDto locTypeDto = new LocTypeDto(); |
| | | if (currentLoc == null) { |
| | | return locTypeDto; |
| | | } |
| | | locTypeDto.setLocType1(normalizeLocType(currentLoc.getLocType1())); |
| | | locTypeDto.setLocType2(normalizeLocType(currentLoc.getLocType2())); |
| | | locTypeDto.setLocType3(normalizeLocType(currentLoc.getLocType3())); |
| | | return locTypeDto; |
| | | } |
| | | |
| | | private Short normalizeLocType(Short locType) { |
| | | return locType == null || locType <= 0 ? null : locType; |
| | | } |
| | | |
| | | private void updateReassignTargetLoc(LocMast targetLoc, WrkMast wrkMast, LocMast currentLoc, Date now) { |
| | | targetLoc.setLocSts("S"); |
| | | targetLoc.setModiUser(WCS_SYNC_USER); |
| | | targetLoc.setModiTime(now); |
| | | if (!Cools.isEmpty(wrkMast.getBarcode())) { |
| | | targetLoc.setBarcode(wrkMast.getBarcode()); |
| | | } else if (!Cools.isEmpty(currentLoc) && !Cools.isEmpty(currentLoc.getBarcode())) { |
| | | targetLoc.setBarcode(currentLoc.getBarcode()); |
| | | } else { |
| | | targetLoc.setBarcode(""); |
| | | } |
| | | if (wrkMast.getScWeight() != null) { |
| | | targetLoc.setScWeight(wrkMast.getScWeight()); |
| | | } else if (!Cools.isEmpty(currentLoc) && currentLoc.getScWeight() != null) { |
| | | targetLoc.setScWeight(currentLoc.getScWeight()); |
| | | } else { |
| | | targetLoc.setScWeight(BigDecimal.ZERO); |
| | | } |
| | | if (!locMastService.updateById(targetLoc)) { |
| | | throw new CoolException("改变库位状态失败"); |
| | | } |
| | | } |
| | | |
| | | private void updateReassignWorkMast(WrkMast wrkMast, StartupDto startupDto, Date now) { |
| | | wrkMast.setLocNo(startupDto.getLocNo()); |
| | | wrkMast.setCrnNo(startupDto.getCrnNo()); |
| | | if (startupDto.getStaNo() != null) { |
| | | wrkMast.setStaNo(startupDto.getStaNo()); |
| | | } |
| | | wrkMast.setWrkSts(2L); |
| | | wrkMast.setModiUser(WCS_SYNC_USER); |
| | | wrkMast.setModiTime(now); |
| | | if (!wrkMastService.updateById(wrkMast)) { |
| | | throw new CoolException("修改工作档失败"); |
| | | } |
| | | } |
| | | |
| | | private void releaseOldReservedLocIfNeeded(LocMast currentLoc, String newLocNo, Date now) { |
| | | if (currentLoc == null || Cools.isEmpty(currentLoc.getLocNo()) || currentLoc.getLocNo().equals(newLocNo)) { |
| | | return; |
| | | } |
| | | if (!"S".equals(currentLoc.getLocSts())) { |
| | | return; |
| | | } |
| | | currentLoc.setLocSts("O"); |
| | | currentLoc.setBarcode(""); |
| | | currentLoc.setScWeight(BigDecimal.ZERO); |
| | | currentLoc.setModiUser(WCS_SYNC_USER); |
| | | currentLoc.setModiTime(now); |
| | | if (!locMastService.updateById(currentLoc)) { |
| | | throw new CoolException("释放原目标库位失败"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 按任务类型选择 WCS 接口地址。 |
| | | * in -> 入库接口 |