feat(oms,wms,system): OMS下单冻结库存(防超卖)——仓库级库存锁定模式
- 仓库新增stock_lock_mode开关(1-下单冻结 2-分配库存冻结默认),查询/独立切换接口+在途冻结单切换守卫 - WMS新增out_order_freeze_record冻结记录表:下单冻结/编辑原子重锁/取消解冻/分配承接/交接扣减/反审还原全状态机,条件更新防并发超卖 - OMS下单即冻结(失败阻断+落库失败补偿解冻)、已下发禁编辑、cancelIssueOrder补调WMS清理(修存量不同步)、cancelAuditState镜像还原修复 - 达梦SQL脚本3个(WAREHOUSE加列/冻结记录建表/主键列名修复),测试库已执行并全流程实测通过
This commit is contained in:
@@ -21,7 +21,7 @@ import java.util.Map;
|
||||
* @description: TODO
|
||||
* @date 2024/5/10 8:58
|
||||
**/
|
||||
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE,url = "http://10.33.0.109:8016",fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
@FeignClient(contextId = "remoteWmsServiceFeign",value = ServiceNameConstants.WMS_SERVICE,fallbackFactory = RemoteWmsFallbackFactory.class, configuration = FeignAutoConfiguration.class)
|
||||
public interface WmsServiceFeign {
|
||||
|
||||
/**
|
||||
@@ -112,11 +112,46 @@ public interface WmsServiceFeign {
|
||||
|
||||
/**
|
||||
* oms下发前库存校验:可用库存不足时返回错误,OMS据此在推送前拦截下发,
|
||||
* 避免单据先落库、分配才失败而在WMS残留"已审核"状态的垃圾单
|
||||
* 避免单据先落库、分配才失败而在WMS残留"已审核"状态的垃圾单。
|
||||
* businessOrderNumber(可空):OMS出库业务单号,下单冻结模式下校验可用量=库存可用+本单冻结记录量
|
||||
*/
|
||||
@ApiOperation("oms下发前库存校验")
|
||||
@PostMapping(value = "/stockOutOrderApi/checkOmsAssignInventory")
|
||||
public AjaxResult checkOmsAssignInventory(@RequestBody List<OutMaterialDetail> outMaterialDetails);
|
||||
public AjaxResult checkOmsAssignInventory(@RequestBody List<OutMaterialDetail> outMaterialDetails,
|
||||
@RequestParam(value = "businessOrderNumber", required = false) String businessOrderNumber);
|
||||
|
||||
/**
|
||||
* oms出库业务单下单冻结库存(防超卖):WMS按明细冻结库存(可用-、冻结+,库存数量不变),
|
||||
* 条件更新防并发超卖,任一行可用不足整体失败并返回错误;同业务单号幂等。
|
||||
* 冻结失败必须阻断OMS下单(返回非200由OMS整体回滚)。
|
||||
*/
|
||||
@ApiOperation("oms出库业务单下单冻结库存")
|
||||
@PostMapping(value = "/stockOutOrderApi/omsFreezeInventory")
|
||||
public AjaxResult omsFreezeInventory(@RequestBody OmsFreezeInventoryParam param);
|
||||
|
||||
/**
|
||||
* oms出库业务单取消/删除-释放冻结库存:可用+、冻结-(库存数量不变);按业务单号幂等;
|
||||
* 冻结已被执行单承接时拒绝(须先取消下发)
|
||||
*/
|
||||
@ApiOperation("oms出库业务单释放冻结库存")
|
||||
@PostMapping(value = "/stockOutOrderApi/omsUnfreezeInventory")
|
||||
public AjaxResult omsUnfreezeInventory(@RequestBody OmsFreezeInventoryParam param);
|
||||
|
||||
/**
|
||||
* oms出库业务单编辑-原子重锁:WMS同一事务内先释放原冻结再按新明细重新冻结,
|
||||
* 任一新明细可用不足整体回滚(旧冻结同样还原),满足"先释放再重新锁定"原子性要求
|
||||
*/
|
||||
@ApiOperation("oms出库业务单编辑重锁库存")
|
||||
@PostMapping(value = "/stockOutOrderApi/omsRelockInventory")
|
||||
public AjaxResult omsRelockInventory(@RequestBody OmsFreezeInventoryParam param);
|
||||
|
||||
/**
|
||||
* 仓库是否存在活跃冻结记录(status in 1-业务单冻结 2-执行单承接):
|
||||
* 仓库"库存锁定模式"(stock_lock_mode)切换守卫,存在在途冻结单时禁止切换
|
||||
*/
|
||||
@ApiOperation("仓库是否存在活跃冻结记录")
|
||||
@GetMapping(value = "/stockOutOrderApi/hasActiveFreezeByWarehouse/{warehouseId}")
|
||||
public AjaxResult hasActiveFreezeByWarehouse(@PathVariable("warehouseId") Long warehouseId);
|
||||
|
||||
/**
|
||||
* oms下发单明细保存(返回执行结果,明细保存含自动审核链路,失败时OMS据此回滚)
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.mhd.system.api.domain;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* OMS出库业务单冻结库存请求参数
|
||||
*
|
||||
* @description OMS下单冻结库存模式(防超卖):OMS出库业务单「下单」即冻结WMS库存
|
||||
* (可用-、冻结+,库存数量不变,库存数量=可用数量+冻结数量);
|
||||
* 「编辑」原子释放旧冻结+按新明细重锁;「取消」释放冻结。
|
||||
* 冻结/解冻以业务单号为幂等键。
|
||||
* @date 2026-09-12
|
||||
*/
|
||||
@Data
|
||||
public class OmsFreezeInventoryParam implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("OMS出库业务单号(幂等键)")
|
||||
private String outOrderNumber;
|
||||
|
||||
@ApiModelProperty("执行出库单号(预留,冻结/解冻/重锁时不使用)")
|
||||
private String executionOrderNumber;
|
||||
|
||||
@ApiModelProperty("库存行ID集合(预留)")
|
||||
private List<Long> materialInventoryIds;
|
||||
|
||||
@ApiModelProperty("出库明细列表(须携带 materialInventoryId 定位库存行)")
|
||||
private List<OutMaterialDetail> details;
|
||||
|
||||
@ApiModelProperty("操作人ID(Feign调用可能无登录上下文时的兜底)")
|
||||
private Long operatorId;
|
||||
|
||||
@ApiModelProperty("操作人姓名(Feign调用可能无登录上下文时的兜底)")
|
||||
private String operatorName;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remark;
|
||||
}
|
||||
@@ -124,6 +124,10 @@ public class WarehouseFeignPO extends BaseVOEntity{
|
||||
@Excel(name = "作业模式")
|
||||
private String workMode;
|
||||
|
||||
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结")
|
||||
@Excel(name = "库存锁定模式: 1-下单冻结 2-分配库存冻结")
|
||||
private Integer stockLockMode;
|
||||
|
||||
@ApiModelProperty("订单号生成规则(0-日期累加 1-历史累加)")
|
||||
@Excel(name = "单号生成规则")
|
||||
private String orderNoGenerateRule;
|
||||
|
||||
+25
-1
@@ -102,11 +102,35 @@ public class RemoteWmsFallbackFactory implements FallbackFactory<WmsServiceFeign
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult checkOmsAssignInventory(List<OutMaterialDetail> outMaterialDetails) {
|
||||
public AjaxResult checkOmsAssignInventory(List<OutMaterialDetail> outMaterialDetails, String businessOrderNumber) {
|
||||
//校验接口本身不可用时返回错误,OMS会阻止下发(不能在WMS状态未知时盲目推送)
|
||||
return AjaxResult.error("WMS库存校验服务不可用:" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult omsFreezeInventory(OmsFreezeInventoryParam param) {
|
||||
//返回错误而非静默成功:下单冻结失败必须阻断OMS下单落库(冻结成功与否状态未知时不允许继续)
|
||||
return AjaxResult.error("WMS下单冻结库存失败(服务降级):" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult omsUnfreezeInventory(OmsFreezeInventoryParam param) {
|
||||
//返回错误而非静默成功:解冻失败让OMS取消/删除感知(解冻可重试,WMS解冻幂等)
|
||||
return AjaxResult.error("WMS释放冻结库存失败(服务降级):" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult omsRelockInventory(OmsFreezeInventoryParam param) {
|
||||
//返回错误而非静默成功:编辑重锁是原子操作,失败必须让OMS编辑整体回滚
|
||||
return AjaxResult.error("WMS编辑重锁库存失败(服务降级):" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult hasActiveFreezeByWarehouse(Long warehouseId) {
|
||||
//返回错误(fail-closed):模式切换守卫校验不可用时拒绝切换,避免在途冻结单语义错乱
|
||||
return AjaxResult.error("WMS冻结记录校验服务不可用:" + cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AjaxResult omsInOrderAddDetail(List<InMaterialDetail> inMaterialDetails) {
|
||||
//返回错误而非静默成功:明细保存(含自动审核)失败必须让OMS感知并回滚下发标记
|
||||
|
||||
Reference in New Issue
Block a user