diff --git a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java index 8b943b6..0fc5d94 100644 --- a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java +++ b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java @@ -5,11 +5,13 @@ public enum ConfigMapKeyEnum { URL_WCS_TASK("URL_WCS_TASK"), URL_NEW_DESTINATION("URL_NEW_DESTINATION"), URL_WCS_PICK_TASK("URL_WCS_PICK_TASK"), + URL_WCS_CANCEL_PICK_TASK("URL_WCS_CANCEL_PICK_TASK"), URL_WCS_E_TASK("URL_WCS_E_TASK"), URL_WCS_DISPOSE_VEHICLE("URL_WCS_DISPOSE_VEHICLE"), CREATE_WORK("CREATE_WORK"), START_WORK("START_WORK"), SEND_TASK("SEND_TASK"), + ALLOW_EMPTY_BACK("ALLOW_EMPTY_BACK"), SEND_PICK_OUT_TASK("SEND_PICK_OUT_TASK"), MAX_VEHICLE_NUMS("MAX_VEHICLE_NUMS"), MAX_WCS_ACCEPT_NUMS("MAX_WCS_ACCEPT_NUMS"), diff --git a/src/main/java/com/wms/controller/ExcelController.java b/src/main/java/com/wms/controller/ExcelController.java index 765d7ae..5ff1379 100644 --- a/src/main/java/com/wms/controller/ExcelController.java +++ b/src/main/java/com/wms/controller/ExcelController.java @@ -380,6 +380,7 @@ public class ExcelController { if (needKanbanQuantity.compareTo(BigDecimal.ZERO) <= 0) { break; } + needKanbanQuantity = needKanbanQuantity.subtract(BigDecimal.ONE); needKanbanList.add(kanbanEntity); } if (!needKanbanList.isEmpty()) { diff --git a/src/main/java/com/wms/controller/StockController.java b/src/main/java/com/wms/controller/StockController.java index 22c4dc4..7dd0da1 100644 --- a/src/main/java/com/wms/controller/StockController.java +++ b/src/main/java/com/wms/controller/StockController.java @@ -1,13 +1,12 @@ package com.wms.controller; import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.wms.annotation.MyLog; -import com.wms.constants.enums.ResponseCode; -import com.wms.constants.enums.StockUpdateReasonEnum; -import com.wms.constants.enums.VehicleStatus; +import com.wms.constants.enums.*; import com.wms.entity.app.ResponseEntity; import com.wms.entity.app.dto.PageDto; import com.wms.entity.app.dto.extend.StockDetailInfo; @@ -16,6 +15,7 @@ import com.wms.entity.app.request.StockQuery; import com.wms.entity.app.request.StockUpdateRecordQuery; import com.wms.entity.app.vo.StockUpdateRecordVo; import com.wms.entity.app.vo.StockVo; +import com.wms.entity.app.wcs.WcsStandTaskRequest; import com.wms.entity.table.*; import com.wms.service.*; import com.wms.utils.HttpUtils; @@ -35,9 +35,11 @@ import org.springframework.web.bind.annotation.*; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Objects; +import static com.wms.config.InitLocalConfig.configMap; import static com.wms.constants.WmsConstants.MYSQL_JSON_CI; import static com.wms.utils.StringUtils.convertJsonString; @@ -81,6 +83,14 @@ public class StockController { * 站台要料服务 */ private final GoodsToStationService goodsToStationService; + /** + * 日志服务 + */ + private final LogService logService; + /** + * 工作流服务 + */ + private final WorkFlowService workFlowService; /** * 请求头部信息 */ @@ -307,6 +317,7 @@ public class StockController { /** * 查询库存更新记录 + * * @param stockUpdateRecordQuery 记录查询参数 * @return 查询结果 */ @@ -388,32 +399,123 @@ public class StockController { List pickTasks = pickTaskService.list(new LambdaQueryWrapper() .eq(PickTask::getVehicleId, handleRequest.getVehicleId()) .ne(PickTask::getPickStatus, 2)); - // 找出当前料箱有没有其他料也需要用 - List otherOutsideVehicles = outsideVehiclesService.list(new LambdaQueryWrapper() - .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId()) - .ne(OutsideVehicles::getGoodsId, handleRequest.getGoodsId())); - if (otherOutsideVehicles != null && !otherOutsideVehicles.isEmpty()) { - // 找出其需要的拣选任务 - for (OutsideVehicles outsideVehicle : otherOutsideVehicles) { - // 找出这个料的对应的goodsToStation - + List updatedGoodsToStationList = new ArrayList<>(); + if (pickTasks != null && !pickTasks.isEmpty()) { + List standIds = pickTasks.stream().map(PickTask::getStandId).distinct().toList(); + List otherGoodsStandIds = new ArrayList<>(); + List currentGoodsStandIds = new ArrayList<>(); + // 找出当前料箱有没有其他料也需要用 + List otherOutsideVehicles = outsideVehiclesService.list(new LambdaQueryWrapper() + .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId()) + .ne(OutsideVehicles::getGoodsId, handleRequest.getGoodsId())); + if (otherOutsideVehicles != null && !otherOutsideVehicles.isEmpty()) { + // 找出其需要的拣选任务 + for (OutsideVehicles outsideVehicle : otherOutsideVehicles) { + // 找出这个料的对应的goodsToStation + List goodsToStations = goodsToStationService.list(new LambdaQueryWrapper() + .eq(GoodsToStation::getGoodsId, outsideVehicle.getGoodsId())); + for (GoodsToStation goodsToStation : goodsToStations) { + // 找出这个料对应的standId + if (standIds.contains(goodsToStation.getWorkStation())) { + if (!otherGoodsStandIds.contains(goodsToStation.getWorkStation())) { + otherGoodsStandIds.add(goodsToStation.getWorkStation()); + } + } + } + } + } + // 当前料 + OutsideVehicles currentOutsideVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper() + .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId()) + .eq(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()) + .last("limit 1")); + if (currentOutsideVehicle != null) { + // 已经分配的数量 + BigDecimal distributedNum = currentStock.getGoodsRelated().getRemainNum().subtract(currentOutsideVehicle.getRemainNum()); + // 将当前物料的所有goodsToStation + List goodsToStations = goodsToStationService.list(new LambdaQueryWrapper() + .eq(GoodsToStation::getGoodsId, currentOutsideVehicle.getGoodsId())); + for (GoodsToStation goodsToStation : goodsToStations) { + // 找出这个料对应的standId + if (standIds.contains(goodsToStation.getWorkStation())) { + if (!currentGoodsStandIds.contains(goodsToStation.getWorkStation())) { + currentGoodsStandIds.add(goodsToStation.getWorkStation()); + } + } + if (distributedNum.compareTo(BigDecimal.ZERO) > 0) { + // 查询这个料对应的当前站台未完成工作流 + List workFlows = workFlowService.list(new LambdaQueryWrapper() + .eq(WorkFlow::getWorkStation, goodsToStation.getWorkStation()) + .eq(WorkFlow::getGoodsId, goodsToStation.getGoodsId()) + .eq(WorkFlow::getWorkStatus, 1)); + BigDecimal recallNum = BigDecimal.ZERO; + for (WorkFlow workFlow : workFlows) { + // 分配数量无了 + if (distributedNum.compareTo(BigDecimal.ZERO) <= 0) { + break; + } + BigDecimal needNum = workFlow.getNeedNum().subtract(workFlow.getPickedNum()); + if (needNum.compareTo(BigDecimal.ZERO) > 0) { + recallNum = recallNum.add(needNum); + distributedNum = distributedNum.subtract(needNum); + } + } + if (recallNum.compareTo(BigDecimal.ZERO) >0) { + goodsToStation.setDistributedNum(goodsToStation.getDistributedNum().subtract(recallNum)); + goodsToStation.setDistributeStatus(1); + updatedGoodsToStationList.add(goodsToStation); + } + } + } + } + List deleteStandIds = currentGoodsStandIds.stream().filter(s -> !otherGoodsStandIds.contains(s)).toList(); + // 生成需要取消的站台任务 + WcsStandTaskRequest requestSingle = new WcsStandTaskRequest(); + requestSingle.setTaskGroup(WmsUtils.generateId(currentVehicle.getVehicleId())); + requestSingle.setTaskType(1); + requestSingle.setVehicleNo(currentVehicle.getVehicleId()); + requestSingle.setLocation(deleteStandIds); + requestSingle.setRemark("站台拣选任务"); + // 发送任务 + String url = configMap.get(ConfigMapKeyEnum.URL_WCS_CANCEL_PICK_TASK.getConfigKey()); + if (url != null) { + logger.info("向WCS发送取消拣选任务,地址:{},请求详情:{}", url, convertJsonString(requestSingle)); + ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(requestSingle)), ResponseEntity.class); + try { + logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送取消拣选任务", "setConveyTask", convertJsonString(requestSingle), convertJsonString(result), url, LocalDateTime.now(), handleRequest.getUserName())); + } catch (Exception e) { + logger.error("插入日志错误。"); + } + if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { + logger.info("发送取消拣选任务成功。"); + pickTaskService.remove(new LambdaQueryWrapper() + .eq(PickTask::getVehicleId, handleRequest.getVehicleId()) + .in(PickTask::getStandId, deleteStandIds)); + } else { + logger.error("发送取消拣选任务错误:{}", convertJsonString(result)); + rsp.setCode(ResponseCode.ERROR.getCode()); + String returnMessage = "发送取消拣选任务错误。"; + if (result != null) { + returnMessage += result.getMessage(); + } + rsp.setMessage(returnMessage); + return convertJsonString(rsp); + } + } else { + logger.error("WCS发送取消拣选任务地址为空。"); + rsp.setCode(ResponseCode.ERROR.getCode()); + rsp.setMessage("WCS发送取消拣选任务地址为空。"); + return convertJsonString(rsp); } } - // 当前料 - OutsideVehicles currentOutsideVehicle = outsideVehiclesService.getOne(new LambdaQueryWrapper() - .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId()) - .eq(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()) - .last("limit 1")); - if (currentOutsideVehicle != null) { - // 已经分配的数量 - BigDecimal distributedNum = currentStock.getGoodsRelated().getRemainNum().subtract(currentOutsideVehicle.getRemainNum()); - // 将当前物料的所有goodsToStation + // 更新站台要料表 + if (!updatedGoodsToStationList.isEmpty()) { + goodsToStationService.updateBatchById(updatedGoodsToStationList); } - // ----请求wcs接口 - // 将这个料的实际剩余库存数量减去outsideVehicles的剩余数量,得出这个料的分配数量 - // 回退goodsToStation - // ----在请求回库时,需要增 加箱子状态的判断。异常状态---允许回库,但是不生成回库任务 - // 添加库存更新记录 + // 移除流转物料 + outsideVehiclesService.remove(new LambdaQueryWrapper() + .eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId()) + .eq(OutsideVehicles::getGoodsId, handleRequest.getGoodsId())); // 标记料箱 vehicleService.update(new LambdaUpdateWrapper() .set(Vehicle::getVehicleStatus, VehicleStatus.EXCEPTION.getCode()) @@ -421,7 +523,12 @@ public class StockController { .ne(Vehicle::getVehicleStatus, VehicleStatus.EXCEPTION.getCode())); // 删除库存 stockService.removeById(currentStock); + // 添加库存更新记录 + stockUpdateRecordService.addStockUpdateRecord(currentStock, null, StockUpdateReasonEnum.ADD_CLIENT.getReason(), handleRequest.getUserName(), currentStock.getGoodsRelated().getRemainNum()); + logger.info("处理异常库存成功。"); + rsp.setCode(ResponseCode.OK.getCode()); + rsp.setMessage("处理异常库存成功。"); return convertJsonString(rsp); } catch (Exception e) { // 回滚事务 @@ -429,7 +536,7 @@ public class StockController { logger.error("处理异常库存发生异常:{}", e.getMessage()); // 返回其他异常 rsp.setCode(ResponseCode.ERROR.getCode()); - rsp.setMessage(e.getMessage()); + rsp.setMessage("处理异常库存发生异常:" + e.getMessage()); return convertJsonString(rsp); } } diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java index 893501b..86cbd04 100644 --- a/src/main/java/com/wms/controller/TaskController.java +++ b/src/main/java/com/wms/controller/TaskController.java @@ -1960,6 +1960,33 @@ public class TaskController { boolean hasPickTasks = pickTaskService.exists(new LambdaQueryWrapper() .eq(PickTask::getVehicleId, requestBackQuery.getVehicleId())); if (!hasPickTasks) { + // 查询到当前料箱 + Vehicle vehicle = vehicleService.getOne(new LambdaQueryWrapper() + .eq(Vehicle::getVehicleId, requestBackQuery.getVehicleId()) + .last("limit 1")); + if (vehicle != null) { + if (Objects.equals(vehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) { + logger.error("当前箱子{}已在库中,无法回库。", requestBackQuery.getVehicleId()); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("当前箱子" + requestBackQuery.getVehicleId() + "已在库中,无法回库。"); + return convertJsonString(response); + } + if (Objects.equals(vehicle.getVehicleStatus(), VehicleStatus.EXCEPTION.getCode())) { + logger.info("异常箱子,可以离开线体。"); + response.setCode(ResponseCode.OK.getCode()); + response.setMessage("异常箱子,可以离开线体。"); + return convertJsonString(response); + } + } else { + // 查询配置 + String allowEmptyBack = configMap.get(ConfigMapKeyEnum.ALLOW_EMPTY_BACK.getConfigKey()); + if (StringUtils.isEmpty(allowEmptyBack) || !allowEmptyBack.equals("1")) { + logger.error("当前配置不允许新空箱回库。"); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("当前配置不允许新空箱回库。"); + return convertJsonString(response); + } + } // 验证载具号是否重复入库 if (vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, requestBackQuery.getVehicleId()) .and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())))) {