fix(oms,wms):执行单重复下发致WMS收货明细翻倍修复,executeAndIssue获取仓库信息失败修复
一、收货明细翻倍(executionStockInOrderApi/issueOrder下发后,WMS收货管理详情明细×2): 根因:执行单下发接口无防重 + WMS接收端无幂等。executeAndIssue已自动下发过的执行单 仍可被手动再次下发(issueTime已置但无校验),重复推送使WMS插入同号入库主单+第二份 in_material_detail,再生成第二张同号收货单(收货单号"RV-"+入库单号确定性生成), 收货管理详情按单号查明细即双倍。四层防御: 1. OMS执行单issueOrder补防重:issueTime非空拒绝下发(与executeAndIssue对齐), inOrderIds去重防同请求重复推送 2. WMS omsOrderAdd主单幂等:同单号有效单(del_flag=1)已存在则跳过插入 3. WMS omsOrderAddDetail明细幂等:按oms_in_material_detail判重,已存在行不再插入; 未传ID的行保持原插入行为 4. WMS autoAuditOmsInOrder取单补orderByAsc(in_order_id)消除同号取单随机性; auditApprove生成收货单前按收货单号查重过滤,已生成过的单不再重复生成 二、executeAndIssue报"获取仓库信息失败": 1. 明细行warehouseId=0时兜底改用主表仓库(与下发issueOrder兜底逻辑对齐), 不再拿无效仓库ID调system服务 2. executeAndIssue/issueOrder两处报错增强为带仓库ID与错误信息,便于定位 存量已翻倍数据(重复入库单/明细/收货单)需另行软删清理,本次仅防新增
This commit is contained in:
+21
-3
@@ -49,6 +49,7 @@ import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 入库单
|
||||
@@ -564,6 +565,24 @@ public class ExecutionStockInOrderDomainService {
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Boolean issueOrder(ExecutionStockInOrderDO stockInOrderDO) {
|
||||
// 防重复下发校验(与 executeAndIssue 防重逻辑对齐):issueTime 有值表示已下发过。
|
||||
// 此前缺少该校验,executeAndIssue 已自动下发过的执行单仍可被手动再次下发,
|
||||
// WMS接收端无幂等,重复推送导致WMS入库单/明细与收货单明细翻倍
|
||||
List<Long> inOrderIds = stockInOrderDO.getInOrderIds();
|
||||
if (inOrderIds == null || inOrderIds.isEmpty()) {
|
||||
throw new ServiceException("下发失败:未选择单据");
|
||||
}
|
||||
// 入参去重:同一请求内重复ID会导致同一执行单被多次推送WMS
|
||||
List<Long> distinctInOrderIds = inOrderIds.stream().distinct().collect(Collectors.toList());
|
||||
List<ExecutionStockInOrder> checkOrders = stockInOrderService.list(
|
||||
new QueryWrapper<ExecutionStockInOrder>().lambda()
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds));
|
||||
for (ExecutionStockInOrder order : checkOrders) {
|
||||
if (order.getIssueTime() != null) {
|
||||
throw new ServiceException("下发失败:单据[" + order.getInOrderNumber() + "]已下发,不可重复下发;如需重新下发请先取消下发");
|
||||
}
|
||||
}
|
||||
|
||||
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||
|
||||
// 获取用户姓名(优先从UserPo获取,如果为空则使用realname,最后使用username作为兜底)
|
||||
@@ -578,11 +597,10 @@ public class ExecutionStockInOrderDomainService {
|
||||
.set(ExecutionStockInOrder::getUpdateBy, loginUser.getUserid())
|
||||
.set(ExecutionStockInOrder::getUpdateByName, userRealName)
|
||||
.set(ExecutionStockInOrder::getUpdateTime, new Date())
|
||||
.in(ExecutionStockInOrder::getInOrderId, stockInOrderDO.getInOrderIds()));
|
||||
.in(ExecutionStockInOrder::getInOrderId, distinctInOrderIds));
|
||||
|
||||
//todo下发推送到wms
|
||||
List<Long> inOrderIds = stockInOrderDO.getInOrderIds();
|
||||
for (Long inOrderId : inOrderIds) {
|
||||
for (Long inOrderId : distinctInOrderIds) {
|
||||
ExecutionStockInOrder byId = stockInOrderService.getById(inOrderId);
|
||||
StockInOrder stockInOrder = new StockInOrder();
|
||||
BeanUtils.copyProperties(byId, stockInOrder,"inOrderId");
|
||||
|
||||
+7
-3
@@ -652,7 +652,7 @@ public class ReservationStockInOrderDomainService {
|
||||
Long warehouseId1 = reservationStockInOrder.getWarehouseId();
|
||||
AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(warehouseId1);
|
||||
if (!"200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||
throw new ServiceException("获取仓库信息失败");
|
||||
throw new ServiceException("获取仓库信息失败,仓库ID:" + warehouseId1 + ",错误信息:" + ajaxResult.get("msg"));
|
||||
}
|
||||
//仓库信息
|
||||
WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class);
|
||||
@@ -826,7 +826,11 @@ public class ReservationStockInOrderDomainService {
|
||||
.collect(Collectors.groupingBy(ReservationInMaterialDetail::getWarehouseId));
|
||||
List<String> executionInOrderNumbers = new ArrayList<>();
|
||||
materialDetailGroupByWarehouse.forEach((warehouseId, details) -> {
|
||||
if (warehouseId == null) warehouseId = warehouseId1;
|
||||
// 明细行仓库无效(0)时兜底用主表仓库,与下发issueOrder的兜底逻辑对齐;
|
||||
// 无效仓库ID传给system服务获取仓库信息会失败,导致"获取仓库信息失败"
|
||||
if (warehouseId == null || warehouseId == 0L){
|
||||
warehouseId = warehouseId1;
|
||||
}
|
||||
|
||||
Long topOrgId = reservationStockInOrderMapper.getTopOrgId(warehouseId);
|
||||
Long orgId = reservationStockInOrderMapper.getOrgId(warehouseId);
|
||||
@@ -873,7 +877,7 @@ public class ReservationStockInOrderDomainService {
|
||||
// Long warehouseId1 = reservationStockInOrder.getWarehouseId();
|
||||
AjaxResult ajaxResult = systemServiceFeign.getWarehouseInfoByWarehouseId(warehouseId);
|
||||
if (!"200".equals(String.valueOf(ajaxResult.get("code")))) {
|
||||
throw new ServiceException("获取仓库信息失败");
|
||||
throw new ServiceException("获取仓库信息失败,仓库ID:" + warehouseId + ",错误信息:" + ajaxResult.get("msg"));
|
||||
}
|
||||
//仓库信息
|
||||
WarehouseFeignPO warehouseFeignPO = com.alibaba.fastjson.JSON.parseObject(com.alibaba.fastjson2.JSONObject.toJSONString(ajaxResult.get("data")), WarehouseFeignPO.class);
|
||||
|
||||
Reference in New Issue
Block a user