fix(oms,wms): 下单冻结推送OMS镜像丢loginUser致NPE静默失败——O侧库存查询冻结不同步根因修复
- 根因: WMS pushOmsMirror 用 MaterialInventoryParamDO(无loginUser字段)copyProperties到OMS参数, loginUser=null 致 OMS kctzjl 写调整记录时 NPE(先于xgkc执行)→镜像不更新+无调整记录, 异常被 Feign @Async+fallback(return null) 完全吞掉, WMS 侧静默无感知 - 修复1(WMS): pushOmsMirror 显式 setLoginUser, 3 个调用点传入登录态兜底后的 loginUser - 修复2(OMS): kctzjl 补三个文案分支——下单冻结(并入库存冻结:可用-冻结+库存不变, adjustType=3)、下单解冻(并入取消分配:可用+冻结-库存不变)、出库反审-还原冻结(新增:实物+冻结+可用不变, 合并快照两步推送) - 修复3(OMS): omsEdit try-catch 失败 log.error 带 type/kctzType/relateNo/全部匹配键后原样抛出, 推送失败不再无痕(此前连错误日志都没有) - 存量: 在途冻结单 R260915004 镜像需按 16.7 节 SQL 补同步; R260915003 因 RQZ260723005 入库镜像行缺失需先补建镜像行(存量对账问题单独排查)
This commit is contained in:
+44
-4
@@ -25,6 +25,7 @@ import com.mhd.system.api.SystemServiceFeign;
|
|||||||
import com.mhd.system.api.domain.MaterialInventoryOmsParamDO;
|
import com.mhd.system.api.domain.MaterialInventoryOmsParamDO;
|
||||||
import com.mhd.system.api.domain.MaterialInventoryPO;
|
import com.mhd.system.api.domain.MaterialInventoryPO;
|
||||||
import com.mhd.system.api.model.LoginUser;
|
import com.mhd.system.api.model.LoginUser;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -43,6 +44,7 @@ import java.util.stream.Collectors;
|
|||||||
* @author gen
|
* @author gen
|
||||||
* @date 2024-05-29
|
* @date 2024-05-29
|
||||||
*/
|
*/
|
||||||
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMaterialInventoryMapper, ReservationMaterialInventory> implements IReservationMaterialInventoryService {
|
public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMaterialInventoryMapper, ReservationMaterialInventory> implements IReservationMaterialInventoryService {
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -131,6 +133,22 @@ public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMat
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Boolean omsEdit(MaterialInventoryOmsParamDO materialInventoryOmsParamDO) {
|
public Boolean omsEdit(MaterialInventoryOmsParamDO materialInventoryOmsParamDO) {
|
||||||
|
// ★推送处理异常必须留痕:WMS 侧 omsEdit 为 @Async+fallback 静默(失败连 error 日志都没有),
|
||||||
|
// 这里若不记日志,失败将完全无痕(历史 bug:下单冻结推送 loginUser=null 在 kctzjl NPE,
|
||||||
|
// 镜像未更新且全程无日志)。记录匹配键便于定位,记录后原样抛出保持语义
|
||||||
|
try {
|
||||||
|
return doOmsEdit(materialInventoryOmsParamDO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("omsEdit库存镜像更新失败:type={}, kctzType={}, relateNo={}, 匹配键: materialBaseInfoId={}, warehouseId={}, inOrderNumber={}, lotNumber={}, batchNumber={}, purchaseDate={}",
|
||||||
|
materialInventoryOmsParamDO.getType(), materialInventoryOmsParamDO.getKctzType(), materialInventoryOmsParamDO.getRelateNo(),
|
||||||
|
materialInventoryOmsParamDO.getMaterialBaseInfoId(), materialInventoryOmsParamDO.getWarehouseId(),
|
||||||
|
materialInventoryOmsParamDO.getInOrderNumber(), materialInventoryOmsParamDO.getLotNumber(),
|
||||||
|
materialInventoryOmsParamDO.getBatchNumber(), materialInventoryOmsParamDO.getPurchaseDate(), e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Boolean doOmsEdit(MaterialInventoryOmsParamDO materialInventoryOmsParamDO) {
|
||||||
String inOrderNumber = materialInventoryOmsParamDO.getInOrderNumber();
|
String inOrderNumber = materialInventoryOmsParamDO.getInOrderNumber();
|
||||||
String lotNumber = materialInventoryOmsParamDO.getLotNumber();
|
String lotNumber = materialInventoryOmsParamDO.getLotNumber();
|
||||||
String batchNumber = materialInventoryOmsParamDO.getBatchNumber();
|
String batchNumber = materialInventoryOmsParamDO.getBatchNumber();
|
||||||
@@ -293,7 +311,7 @@ public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMat
|
|||||||
}
|
}
|
||||||
inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventory.getMaterialBaseInfoId());
|
inventoryAdjustmentRecord.setMaterialBaseInfoId(materialInventory.getMaterialBaseInfoId());
|
||||||
inventoryAdjustmentRecord.setAdjustType(1L);
|
inventoryAdjustmentRecord.setAdjustType(1L);
|
||||||
if ("库存冻结".equals(adjustAction)) {
|
if ("库存冻结".equals(adjustAction) || "下单冻结".equals(adjustAction)) {
|
||||||
inventoryAdjustmentRecord.setAdjustType(3L);
|
inventoryAdjustmentRecord.setAdjustType(3L);
|
||||||
}
|
}
|
||||||
inventoryAdjustmentRecord.setOrganizationId(materialInventory.getOrganizationId());
|
inventoryAdjustmentRecord.setOrganizationId(materialInventory.getOrganizationId());
|
||||||
@@ -339,8 +357,8 @@ public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMat
|
|||||||
inventoryAdjustmentRecord.setAdjustedGrossWeight(nz(materialInventory.getGrossWeight()));//毛重
|
inventoryAdjustmentRecord.setAdjustedGrossWeight(nz(materialInventory.getGrossWeight()));//毛重
|
||||||
inventoryAdjustmentRecord.setAdjustedVolume(nz(materialInventory.getVolume()));//体积
|
inventoryAdjustmentRecord.setAdjustedVolume(nz(materialInventory.getVolume()));//体积
|
||||||
inventoryAdjustmentRecord.setAdjustedArea(nz(materialInventory.getArea()));//积
|
inventoryAdjustmentRecord.setAdjustedArea(nz(materialInventory.getArea()));//积
|
||||||
} else if ("取消分配".equals(adjustAction)) {
|
} else if ("取消分配".equals(adjustAction) || "下单解冻".equals(adjustAction)) {
|
||||||
// 与分配相反:可用增加、冻结减少,总库存不变
|
// 与分配相反:可用增加、冻结减少,总库存不变("下单解冻":OMS下单冻结后的取消/编辑重锁释放,同数学)
|
||||||
BigDecimal invBefore = nz(materialInventory.getInventoryQuantity());
|
BigDecimal invBefore = nz(materialInventory.getInventoryQuantity());
|
||||||
BigDecimal allocBefore = nz(materialInventory.getAllocationQuantity());
|
BigDecimal allocBefore = nz(materialInventory.getAllocationQuantity());
|
||||||
BigDecimal freezeBefore = nz(materialInventory.getFreezeQuantity());
|
BigDecimal freezeBefore = nz(materialInventory.getFreezeQuantity());
|
||||||
@@ -434,7 +452,8 @@ public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMat
|
|||||||
inventoryAdjustmentRecord.setAdjustedGrossWeight(materialInventory.getGrossWeight());
|
inventoryAdjustmentRecord.setAdjustedGrossWeight(materialInventory.getGrossWeight());
|
||||||
inventoryAdjustmentRecord.setAdjustedVolume(materialInventory.getVolume());
|
inventoryAdjustmentRecord.setAdjustedVolume(materialInventory.getVolume());
|
||||||
inventoryAdjustmentRecord.setAdjustedArea(materialInventory.getArea());
|
inventoryAdjustmentRecord.setAdjustedArea(materialInventory.getArea());
|
||||||
} else if ("库存冻结".equals(adjustAction)) {
|
} else if ("库存冻结".equals(adjustAction) || "下单冻结".equals(adjustAction)) {
|
||||||
|
// "下单冻结"(OMS防超卖):总库存不变;可用减少、冻结增加——与"库存冻结"同数学
|
||||||
inventoryAdjustmentRecord.setAllocationBeforeQuantity(nz(materialInventory.getAllocationQuantity()));
|
inventoryAdjustmentRecord.setAllocationBeforeQuantity(nz(materialInventory.getAllocationQuantity()));
|
||||||
inventoryAdjustmentRecord.setAllocationAfterQuantity(nz(materialInventory.getAllocationQuantity()).subtract(qty));
|
inventoryAdjustmentRecord.setAllocationAfterQuantity(nz(materialInventory.getAllocationQuantity()).subtract(qty));
|
||||||
inventoryAdjustmentRecord.setFreezeBeforeQuantity(nz(materialInventory.getFreezeQuantity()));
|
inventoryAdjustmentRecord.setFreezeBeforeQuantity(nz(materialInventory.getFreezeQuantity()));
|
||||||
@@ -488,6 +507,27 @@ public class ReservationMaterialInventoryImpl extends ServiceImpl<ReservationMat
|
|||||||
inventoryAdjustmentRecord.setAdjustedGrossWeight(materialInventory.getGrossWeight());
|
inventoryAdjustmentRecord.setAdjustedGrossWeight(materialInventory.getGrossWeight());
|
||||||
inventoryAdjustmentRecord.setAdjustedVolume(materialInventory.getVolume());
|
inventoryAdjustmentRecord.setAdjustedVolume(materialInventory.getVolume());
|
||||||
inventoryAdjustmentRecord.setAdjustedArea(materialInventory.getArea());
|
inventoryAdjustmentRecord.setAdjustedArea(materialInventory.getArea());
|
||||||
|
} else if ("出库反审-还原冻结".equals(adjustAction)) {
|
||||||
|
// OMS下单冻结模式出库反审:还原为"下单已冻结待出库"——实物增加、冻结增加、可用不变,
|
||||||
|
// 与交接扣减 ckjj(库存-冻结-)互逆;WMS 侧以 type=1+type=7 两步推送合成,此处记录一步合并快照
|
||||||
|
BigDecimal invBefore = nz(materialInventory.getInventoryQuantity());
|
||||||
|
BigDecimal allocBefore = nz(materialInventory.getAllocationQuantity());
|
||||||
|
BigDecimal freezeBefore = nz(materialInventory.getFreezeQuantity());
|
||||||
|
inventoryAdjustmentRecord.setInventoryBeforeQuantity(invBefore);
|
||||||
|
inventoryAdjustmentRecord.setInventoryAfterQuantity(invBefore.add(qty));
|
||||||
|
inventoryAdjustmentRecord.setAllocationBeforeQuantity(allocBefore);
|
||||||
|
inventoryAdjustmentRecord.setAllocationAfterQuantity(allocBefore);
|
||||||
|
inventoryAdjustmentRecord.setFreezeBeforeQuantity(freezeBefore);
|
||||||
|
inventoryAdjustmentRecord.setFreezeAfterQuantity(freezeBefore.add(qty));
|
||||||
|
inventoryAdjustmentRecord.setAdjustType(3L);
|
||||||
|
inventoryAdjustmentRecord.setNetWeight(nz(materialInventory.getNetWeight()));
|
||||||
|
inventoryAdjustmentRecord.setGrossWeight(nz(materialInventory.getGrossWeight()));
|
||||||
|
inventoryAdjustmentRecord.setVolume(nz(materialInventory.getVolume()));
|
||||||
|
inventoryAdjustmentRecord.setArea(nz(materialInventory.getArea()));
|
||||||
|
inventoryAdjustmentRecord.setAdjustedNetWeight(nz(materialInventory.getNetWeight()));
|
||||||
|
inventoryAdjustmentRecord.setAdjustedGrossWeight(nz(materialInventory.getGrossWeight()));
|
||||||
|
inventoryAdjustmentRecord.setAdjustedVolume(nz(materialInventory.getVolume()));
|
||||||
|
inventoryAdjustmentRecord.setAdjustedArea(nz(materialInventory.getArea()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-4
@@ -382,7 +382,7 @@ public class OutOrderFreezeRecordDomainService {
|
|||||||
for (PendingFreeze pending : pendingFreezes) {
|
for (PendingFreeze pending : pendingFreezes) {
|
||||||
insertFreezeRecord(pending.row, pending.quantity, businessOrderNumber, pending.uniqueId, pending.relateNo, holder);
|
insertFreezeRecord(pending.row, pending.quantity, businessOrderNumber, pending.uniqueId, pending.relateNo, holder);
|
||||||
MaterialInventoryParamDO paramDO = buildParamDO(pending.row, pending.quantity, "7", pending.relateNo);
|
MaterialInventoryParamDO paramDO = buildParamDO(pending.row, pending.quantity, "7", pending.relateNo);
|
||||||
pushOmsMirror(paramDO, "下单冻结");
|
pushOmsMirror(paramDO, "下单冻结", holder.loginUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,7 +405,7 @@ public class OutOrderFreezeRecordDomainService {
|
|||||||
record.setFreezeStatus(OutOrderFreezeRecord.STATUS_RELEASED);
|
record.setFreezeStatus(OutOrderFreezeRecord.STATUS_RELEASED);
|
||||||
record.setUpdateTime(new Date());
|
record.setUpdateTime(new Date());
|
||||||
outOrderFreezeRecordService.updateById(record);
|
outOrderFreezeRecordService.updateById(record);
|
||||||
pushOmsMirror(buildParamDO(row, record.getFreezeQuantity(), "3", record.getRelateNo()), "下单解冻");
|
pushOmsMirror(buildParamDO(row, record.getFreezeQuantity(), "3", record.getRelateNo()), "下单解冻", holder.loginUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -454,13 +454,17 @@ public class OutOrderFreezeRecordDomainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 推送OMS镜像库存(type=7下单冻结:可用-冻结+ / type=3下单解冻:可用+冻结-),与分配/交接推送同模式
|
* 推送OMS镜像库存(type=7下单冻结:可用-冻结+ / type=3下单解冻:可用+冻结-),与分配/交接推送同模式。
|
||||||
|
* ★loginUser 必须显式传入:MaterialInventoryParamDO 无 loginUser 字段,copyProperties 不会带过去,
|
||||||
|
* 推过去为 null 时 OMS 侧 kctzjl 写调整记录 loginUser.getUserid() 直接 NPE——
|
||||||
|
* kctzjl 先于 xgkc 执行,NPE 导致镜像完全不更新且异常被 Feign 异步/fallback 吞掉(历史静默失败根因)
|
||||||
*/
|
*/
|
||||||
private void pushOmsMirror(MaterialInventoryParamDO paramDO, String kctzType) {
|
private void pushOmsMirror(MaterialInventoryParamDO paramDO, String kctzType, LoginUser loginUser) {
|
||||||
try {
|
try {
|
||||||
MaterialInventoryOmsParamDO omsParamDO = new MaterialInventoryOmsParamDO();
|
MaterialInventoryOmsParamDO omsParamDO = new MaterialInventoryOmsParamDO();
|
||||||
BeanUtils.copyProperties(paramDO, omsParamDO);
|
BeanUtils.copyProperties(paramDO, omsParamDO);
|
||||||
omsParamDO.setKctzType(kctzType);
|
omsParamDO.setKctzType(kctzType);
|
||||||
|
omsParamDO.setLoginUser(loginUser);
|
||||||
omsServiceFeign.omsEdit(omsParamDO);
|
omsServiceFeign.omsEdit(omsParamDO);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 镜像推送失败不阻断冻结主流程(与分配/交接链路同口径),由OMS侧定时对账兜底
|
// 镜像推送失败不阻断冻结主流程(与分配/交接链路同口径),由OMS侧定时对账兜底
|
||||||
|
|||||||
Reference in New Issue
Block a user