代码更新:

1. 增加新空箱是否允许回库的配置
2. 增加异常库存处理的功能
3. 修改导出看板需求的问题
This commit is contained in:
梁州 2024-10-06 16:15:54 +08:00
parent 113553ba80
commit 77fc18f310
4 changed files with 164 additions and 27 deletions

View File

@ -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"),

View File

@ -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()) {

View File

@ -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<PickTask> pickTasks = pickTaskService.list(new LambdaQueryWrapper<PickTask>()
.eq(PickTask::getVehicleId, handleRequest.getVehicleId())
.ne(PickTask::getPickStatus, 2));
// 找出当前料箱有没有其他料也需要用
List<OutsideVehicles> otherOutsideVehicles = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
.eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId())
.ne(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()));
if (otherOutsideVehicles != null && !otherOutsideVehicles.isEmpty()) {
// 找出其需要的拣选任务
for (OutsideVehicles outsideVehicle : otherOutsideVehicles) {
// 找出这个料的对应的goodsToStation
List<GoodsToStation> updatedGoodsToStationList = new ArrayList<>();
if (pickTasks != null && !pickTasks.isEmpty()) {
List<String> standIds = pickTasks.stream().map(PickTask::getStandId).distinct().toList();
List<String> otherGoodsStandIds = new ArrayList<>();
List<String> currentGoodsStandIds = new ArrayList<>();
// 找出当前料箱有没有其他料也需要用
List<OutsideVehicles> otherOutsideVehicles = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
.eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId())
.ne(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()));
if (otherOutsideVehicles != null && !otherOutsideVehicles.isEmpty()) {
// 找出其需要的拣选任务
for (OutsideVehicles outsideVehicle : otherOutsideVehicles) {
// 找出这个料的对应的goodsToStation
List<GoodsToStation> goodsToStations = goodsToStationService.list(new LambdaQueryWrapper<GoodsToStation>()
.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<OutsideVehicles>()
.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<GoodsToStation> goodsToStations = goodsToStationService.list(new LambdaQueryWrapper<GoodsToStation>()
.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<WorkFlow> workFlows = workFlowService.list(new LambdaQueryWrapper<WorkFlow>()
.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<String> 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<PickTask>()
.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<OutsideVehicles>()
.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<OutsideVehicles>()
.eq(OutsideVehicles::getVehicleId, handleRequest.getVehicleId())
.eq(OutsideVehicles::getGoodsId, handleRequest.getGoodsId()));
// 标记料箱
vehicleService.update(new LambdaUpdateWrapper<Vehicle>()
.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);
}
}

View File

@ -1960,6 +1960,33 @@ public class TaskController {
boolean hasPickTasks = pickTaskService.exists(new LambdaQueryWrapper<PickTask>()
.eq(PickTask::getVehicleId, requestBackQuery.getVehicleId()));
if (!hasPickTasks) {
// 查询到当前料箱
Vehicle vehicle = vehicleService.getOne(new LambdaQueryWrapper<Vehicle>()
.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<Vehicle>().eq(Vehicle::getVehicleId, requestBackQuery.getVehicleId())
.and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())))) {