| | |
| | | import com.vincent.rsf.server.manager.enums.LocStsType; |
| | | import com.vincent.rsf.server.system.utils.SerialRuleUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import lombok.val; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | |
| | | // 验证设备站点 |
| | | DeviceSite deviceSite = validateDeviceSite(param); |
| | | |
| | | // 空板入库:与非空板同一入口,仅不校验组托,只做分配库位、建任务、更新库位 |
| | | if (param.getIoType() != null && param.getIoType().equals(TaskType.TASK_TYPE_EMPITY_IN.type)) { |
| | | return createInTaskForEmptyPallet(param.getBarcode(), param.getSourceStaNo(), param.getLocType1()); |
| | | } |
| | | |
| | | // 提前定义 waitPakin / waitPakinItems,供后续其他入库逻辑使用 |
| | | WaitPakin waitPakin = null; |
| | |
| | | log.warn("[RCS入库申请-自动组托] 入库单编码规则未配置"); |
| | | return; |
| | | } |
| | | // val orderWorkTypeOtherIn = OrderWorkType.ORDER_WORK_TYPE_OTHER_IN.type; |
| | | // .setWkType(orderWorkTypeOtherIn) |
| | | WkOrder order = new WkOrder(); |
| | | order.setCode(ruleCode) |
| | | .setType(OrderType.ORDER_IN.type) |
| | |
| | | */ |
| | | private Task createTask(String ruleCode, String targetLoc, String barcode, |
| | | String targetSite, String sourceSiteNo, Long loginUserId) { |
| | | return createTask(ruleCode, targetLoc, barcode, targetSite, sourceSiteNo, loginUserId, TaskType.TASK_TYPE_IN.type); |
| | | } |
| | | |
| | | /** |
| | | * 创建并保存任务(支持指定任务类型,如空板入库) |
| | | */ |
| | | private Task createTask(String ruleCode, String targetLoc, String barcode, |
| | | String targetSite, String sourceSiteNo, Long loginUserId, Integer taskType) { |
| | | Task task = new Task(); |
| | | task.setTaskCode(ruleCode) |
| | | .setTaskStatus(TaskStsType.GENERATE_IN.id) |
| | | .setTaskType(TaskType.TASK_TYPE_IN.type) |
| | | .setTaskType(taskType != null ? taskType : TaskType.TASK_TYPE_IN.type) |
| | | .setWarehType(WarehType.WAREHOUSE_TYPE_CRN.val) |
| | | .setTargLoc(targetLoc) |
| | | .setBarcode(barcode) |
| | |
| | | if (!updated) { |
| | | throw new CoolException("库位预约失败!!"); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 空板入库:与非空板同一流程(校验站点、分配库位、建任务、更新库位),仅不校验组托、不写任务明细、不更新组托状态。 |
| | | * 由 createInTask 在 ioType=空板时调用;需在设备站点中配置 type=10(空板入库)的站点路径。 |
| | | */ |
| | | private InTaskMsgDto createInTaskForEmptyPallet(String barcode, String staNo, Integer type) { |
| | | TaskInParam param = new TaskInParam(); |
| | | param.setBarcode(barcode); |
| | | param.setSourceStaNo(staNo); |
| | | param.setLocType1(type != null ? type : 1); |
| | | param.setIoType(TaskType.TASK_TYPE_EMPITY_IN.type); |
| | | param.setUser(1L); |
| | | |
| | | // 校验设备站点(需配置 type=10 空板入库的站点) |
| | | DeviceSite deviceSite = validateDeviceSite(param); |
| | | |
| | | // 检查该托盘号是否已有空板入库任务,有则复用 |
| | | Task existingInTask = taskService.getOne(new LambdaQueryWrapper<Task>() |
| | | .eq(Task::getBarcode, barcode) |
| | | .eq(Task::getTaskType, TaskType.TASK_TYPE_EMPITY_IN.type) |
| | | .orderByDesc(Task::getCreateTime) |
| | | .last("LIMIT 1")); |
| | | if (existingInTask != null) { |
| | | log.info("找到该托盘号已有空板入库任务,复用 - 任务编码:{},箱号:{}", existingInTask.getTaskCode(), barcode); |
| | | if (StringUtils.isNotBlank(staNo) && !staNo.equals(existingInTask.getOrgSite())) { |
| | | existingInTask.setOrgSite(staNo); |
| | | taskService.updateById(existingInTask); |
| | | } |
| | | InTaskMsgDto msgDto = new InTaskMsgDto(); |
| | | msgDto.setWorkNo(existingInTask.getTaskCode()); |
| | | msgDto.setTaskId(existingInTask.getId()); |
| | | msgDto.setLocNo(existingInTask.getTargLoc()); |
| | | msgDto.setSourceStaNo(existingInTask.getOrgSite()); |
| | | msgDto.setStaNo(existingInTask.getTargSite()); |
| | | return msgDto; |
| | | } |
| | | |
| | | // 该托盘已在库或出库中,不可重复申请空板入库 |
| | | List<Loc> inStock = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getBarcode, barcode)); |
| | | if (!inStock.isEmpty()) { |
| | | throw new CoolException("barcode=" + barcode + ": 该托盘已在库,不可重复申请入库"); |
| | | } |
| | | Task outboundTask = taskService.getOne(new LambdaQueryWrapper<Task>() |
| | | .eq(Task::getBarcode, barcode) |
| | | .in(Task::getTaskType, Arrays.asList(TaskType.TASK_TYPE_OUT.type, TaskType.TASK_TYPE_EMPITY_OUT.type, |
| | | TaskType.TASK_TYPE_PICK_AGAIN_OUT.type, TaskType.TASK_TYPE_CHECK_OUT.type)) |
| | | .lt(Task::getTaskStatus, TaskStsType.COMPLETE_OUT.id)); |
| | | if (outboundTask != null) { |
| | | throw new CoolException("barcode=" + barcode + ": 该托盘出库中未完成,不可申请入库"); |
| | | } |
| | | |
| | | InTaskMsgDto locNo; |
| | | try { |
| | | locNo = getLocNo(param); |
| | | } catch (Exception e) { |
| | | throw new CoolException("获取空板入库库位失败:" + e.getMessage()); |
| | | } |
| | | if (locNo == null || StringUtils.isBlank(locNo.getLocNo())) { |
| | | throw new CoolException("未找到可用的空库位,请检查库区与设备站点配置(空板入库需配置 type=10 的站点)"); |
| | | } |
| | | String ruleCode = generateTaskCode(); |
| | | String targetSite = StringUtils.isNotBlank(deviceSite.getDeviceSite()) ? deviceSite.getDeviceSite() : staNo; |
| | | Task task = createTask(ruleCode, locNo.getLocNo(), barcode, targetSite, staNo, param.getUser(), TaskType.TASK_TYPE_EMPITY_IN.type); |
| | | updateLocStatus(task.getTargLoc(), barcode); |
| | | locNo.setWorkNo(ruleCode); |
| | | locNo.setTaskId(task.getId()); |
| | | log.info("[空板入库] 已创建任务: {}, 库位: {}, 料箱: {}", ruleCode, locNo.getLocNo(), barcode); |
| | | return locNo; |
| | | } |
| | | |
| | | /** |
| | |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public R allocateLocation(String barcode, String staNo, Integer type) { |
| | | public R allocateLocation(String barcode, String staNo, Integer type, Boolean full) { |
| | | log.info("========== 开始申请入库任务,分配库位 =========="); |
| | | log.info("料箱码:{},入库站点:{},入库类型:{}", barcode, staNo, type); |
| | | log.info("料箱码:{},入库站点:{},入库类型:{},空板:{}", barcode, staNo, type, full); |
| | | |
| | | // 构建 TaskInParam 参数,与 /wcs/create/in/task 接口参数一致 |
| | | // 统一走 createInTask:空板(full=true)仅不校验组托,仍校验站点、分配库位、建任务;非空板需组托 |
| | | TaskInParam param = new TaskInParam(); |
| | | param.setBarcode(barcode); |
| | | param.setSourceStaNo(staNo); |
| | | param.setIoType(TaskType.TASK_TYPE_IN.type); // 入库类型 |
| | | param.setLocType1(type); // 库位类型(高低检测信号) |
| | | param.setUser(1L); // 默认用户ID,可以根据实际需求调整 |
| | | param.setLocType1(type != null ? type : 1); |
| | | param.setUser(1L); |
| | | param.setIoType(Boolean.TRUE.equals(full) ? TaskType.TASK_TYPE_EMPITY_IN.type : TaskType.TASK_TYPE_IN.type); |
| | | |
| | | // 调用 createInTask 方法,创建完整的入库任务 |
| | | // 该方法会执行以下流程: |
| | | // 1. 验证设备站点 |
| | | // 2. 验证组拖状态 |
| | | // 3. 检查是否有匹配的入库任务(拣料/盘点入库会匹配状态199并更新为2) |
| | | // 4. 生成任务编码(如果需要创建新任务) |
| | | // 5. 获取库位号 |
| | | // 6. 创建并保存任务(如果需要创建新任务) |
| | | // 7. 更新库位状态 |
| | | // 8. 获取并验证组拖明细 |
| | | // 9. 创建并保存任务明细 |
| | | // 10. 更新组托状态 |
| | | InTaskMsgDto msgDto = createInTask(param); |
| | | |
| | | // 查询任务当前状态 |
| | |
| | | .set(Task::getUpdateTime, new Date())); |
| | | |
| | | if (statusUpdated) { |
| | | log.info("新创建的入库任务状态已更新为2(RCS任务已下发) - 任务编码:{}", task.getTaskCode()); |
| | | task = taskService.getById(task.getId()); |
| | | log.info("新创建的入库任务状态已更新为2(RCS任务已下发) - 任务编码:{},当前状态:{}", task.getTaskCode(), task != null ? task.getTaskStatus() : null); |
| | | } else { |
| | | task = taskService.getById(task.getId()); |
| | | log.warn("新创建的入库任务状态更新为2失败,可能状态已变更 - 任务编码:{},当前状态:{}", |
| | | task.getTaskCode(), task.getTaskStatus()); |
| | | task.getTaskCode(), task != null ? task.getTaskStatus() : null); |
| | | } |
| | | } else if (taskStatus != null && taskStatus.equals(TaskStsType.WCS_EXECUTE_IN.id)) { |
| | | log.info("入库任务状态已经是2(RCS任务已下发),无需更新 - 任务编码:{}", task.getTaskCode()); |