feat(oms,wms): 出库全链路物料明细/单头增加库存锁定模式字段(存储+回显)

- 出库业务单明细/执行单明细/WMS出库明细/拣货明细/复核明细新增stockLockMode; 业务单单头新增JSON数组字段、执行单单头新增单值字段
- 下单/编辑时按明细行仓库实时判定(1-下单冻结 2-分配库存冻结默认), 下发后沿 执行单→WMS推单→拣货→复核 逐级复制继承, 交接单回显内存组装
- 业务单单头JSON两段式: 下单按仓写入(无执行单号), 下发覆盖为执行单级(带CK执行单号)
- WMS自建/通知/调拨单明细固定2; TZPD外部推入/老预约单下发路径固定2
- 达梦SQL脚本(OMS库4表+WMS库3表), 明细列DEFAULT 2存量自动回填
This commit is contained in:
rcx
2026-09-15 09:30:54 +08:00
parent 50423b4e4b
commit be5e3fc5ee
34 changed files with 259 additions and 7 deletions
@@ -169,6 +169,9 @@ public class OutMaterialDetail extends BaseVOEntity {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -169,6 +169,9 @@ public class ExecutionOutMaterialDetail extends BaseVOEntity {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 下发时从业务单明细复制")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -183,6 +183,9 @@ public class ExecutionOutMaterialDetailPO extends ExecutionStockOutOrderBaseDO {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -519,4 +519,7 @@ public class ExecutionStockOutOrder extends BaseVOEntity {
@ApiModelProperty("反审标记: 0-无 1-已反审(业务单反审时软删del_flag=2并打标记)") @ApiModelProperty("反审标记: 0-无 1-已反审(业务单反审时软删del_flag=2并打标记)")
private Integer reverseFlag; private Integer reverseFlag;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 下发时按该仓明细行取值")
private Integer stockLockMode;
} }
@@ -31,6 +31,8 @@ public class ExecutionStockOutOrderPO extends BaseVOEntity {
private Long outOrderId; private Long outOrderId;
@ApiModelProperty("反审标记: 1-已反审(反审软删归档, 【已反审】tab按 delFlag=2+reverseFlag=1 查询)") @ApiModelProperty("反审标记: 1-已反审(反审软删归档, 【已反审】tab按 delFlag=2+reverseFlag=1 查询)")
private Integer reverseFlag; private Integer reverseFlag;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 下发时按该仓明细行取值")
private Integer stockLockMode;
@ApiModelProperty("总价") @ApiModelProperty("总价")
@Excel(name = "总价") @Excel(name = "总价")
private BigDecimal amount; private BigDecimal amount;
@@ -171,6 +171,9 @@ public class ReservationOutMaterialDetail extends BaseVOEntity {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 保存时按行仓库判定")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -184,6 +184,9 @@ public class ReservationOutMaterialDetailPO extends ReservationStockOutOrderBase
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -175,6 +175,9 @@ public class ReservationOutMaterialDetailDO extends BaseVOEntity {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -518,6 +518,9 @@ public class ReservationStockOutOrder extends BaseVOEntity {
@ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)")
private Integer reverseStatus; private Integer reverseStatus;
@ApiModelProperty("库存锁定模式JSON(多仓多执行单): [{\"executionOrderNumber\":\"CK001\",\"warehouseCode\":\"QZ\",\"warehouseName\":\"青洲仓\",\"stockLockMode\":1}]; 下单按仓写入, 下发后回填执行单号")
private String stockLockModeJson;
@ApiModelProperty("反审人id") @ApiModelProperty("反审人id")
private Long reverseBy; private Long reverseBy;
@@ -541,6 +541,9 @@ public class ReservationStockOutOrderPO extends BaseVOEntity {
@ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)")
private Integer reverseStatus; private Integer reverseStatus;
@ApiModelProperty("库存锁定模式JSON(多仓多执行单): [{\"executionOrderNumber\":\"CK001\",\"warehouseCode\":\"QZ\",\"warehouseName\":\"青洲仓\",\"stockLockMode\":1}]; 下单按仓写入, 下发后回填执行单号; stockLockMode: 1-下单冻结 2-分配库存冻结")
private String stockLockModeJson;
@ApiModelProperty("反审人id") @ApiModelProperty("反审人id")
private Long reverseBy; private Long reverseBy;
@@ -594,6 +594,9 @@ public class ReservationStockOutOrderDO extends BaseVOEntity {
@ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)") @ApiModelProperty("反审状态: 0-无 1-已反审(反审后status回退为1-已创建,重新审核通过自动复位0)")
private Integer reverseStatus; private Integer reverseStatus;
@ApiModelProperty("库存锁定模式JSON(多仓多执行单); 下单按仓写入, 下发后回填执行单号")
private String stockLockModeJson;
@ApiModelProperty("反审人id") @ApiModelProperty("反审人id")
private Long reverseBy; private Long reverseBy;
@@ -227,6 +227,8 @@ public class ReservationStockOutOrderDomainService {
// update / batchInsert 一致前端传计划数量为 quantity outboundQuantity // update / batchInsert 一致前端传计划数量为 quantity outboundQuantity
setMaterialDetailInfo(stockOutOrderDO); setMaterialDetailInfo(stockOutOrderDO);
// 明细行冗余存储库存锁定模式1-下单冻结 2-分配冻结按行仓库判定供回显与下发链路复制
fillDetailStockLockMode(stockOutOrderDO);
stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size()); stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size());
BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(ReservationOutMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal quantity = stockOutOrderDO.getMaterialDetailList().stream().map(ReservationOutMaterialDetailDO::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
stockOutOrderDO.setQuantity(quantity); stockOutOrderDO.setQuantity(quantity);
@@ -287,6 +289,8 @@ public class ReservationStockOutOrderDomainService {
//设置物料信息 //设置物料信息
setMaterialDetailInfo(stockOutOrderDO); setMaterialDetailInfo(stockOutOrderDO);
// 明细行冗余存储库存锁定模式按行仓库判定 insert 同口径
fillDetailStockLockMode(stockOutOrderDO);
//统计种类 //统计种类
stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size()); stockOutOrderDO.setMaterialQuantity(stockOutOrderDO.getMaterialDetailList().size());
//统计总数量 //统计总数量
@@ -331,6 +335,49 @@ public class ReservationStockOutOrderDomainService {
return warehouseFeignPO != null && warehouseFeignPO.getStockLockMode() != null && warehouseFeignPO.getStockLockMode() == 1; return warehouseFeignPO != null && warehouseFeignPO.getStockLockMode() != null && warehouseFeignPO.getStockLockMode() == 1;
} }
/**
* 明细行冗余存储库存锁定模式存储+回显按行仓库 warehouseId 优先空取单头实时判定
* 1-下单冻结 2-分配库存冻结默认保存/编辑时重算幂等下发后随明细复制传递到执行单/WMS
* 供老预约单下发路径复用public
*/
public void fillDetailStockLockMode(List<ReservationOutMaterialDetailDO> details, Long defaultWarehouseId) {
if (CollectionUtils.isEmpty(details)) {
return;
}
for (ReservationOutMaterialDetailDO detail : details) {
Long warehouseId = detail.getWarehouseId() != null ? detail.getWarehouseId() : defaultWarehouseId;
detail.setStockLockMode(isOrderFreezeWarehouse(warehouseId) ? 1 : 2);
}
}
private void fillDetailStockLockMode(ReservationStockOutOrderDO stockOutOrderDO) {
fillDetailStockLockMode(stockOutOrderDO.getMaterialDetailList(), stockOutOrderDO.getWarehouseId());
// 单头库存锁定模式JSON仓级元素不含执行单号下发后在 issueOrder/executeAndIssue 覆盖为执行单级
stockOutOrderDO.setStockLockModeJson(buildStockLockModeJsonByDetails(stockOutOrderDO.getMaterialDetailList()));
}
/**
* 按明细行仓库去重组装库存锁定模式JSON
* [{"warehouseId":13,"warehouseCode":"QZ","warehouseName":"青洲仓","stockLockMode":1}]
*/
private String buildStockLockModeJsonByDetails(List<ReservationOutMaterialDetailDO> details) {
if (CollectionUtils.isEmpty(details)) {
return null;
}
Map<Long, Map<String, Object>> warehouseJsonMap = new LinkedHashMap<>();
for (ReservationOutMaterialDetailDO detail : details) {
warehouseJsonMap.computeIfAbsent(detail.getWarehouseId(), k -> {
Map<String, Object> item = new LinkedHashMap<>();
item.put("warehouseId", k);
item.put("warehouseCode", detail.getWarehouseCode());
item.put("warehouseName", detail.getWarehouseName());
item.put("stockLockMode", detail.getStockLockMode() != null ? detail.getStockLockMode() : 2);
return item;
});
}
return JSON.toJSONString(warehouseJsonMap.values());
}
/** /**
* 出库单保存时下单冻结筛选下单冻结模式仓库的明细先冻结WMS库存再落库失败抛异常阻断保存 * 出库单保存时下单冻结筛选下单冻结模式仓库的明细先冻结WMS库存再落库失败抛异常阻断保存
* 下单冻结模式仓库明细强制必选库存批次未关联 materialInventoryId 无法确定冻结哪条库存行直接阻断 * 下单冻结模式仓库明细强制必选库存批次未关联 materialInventoryId 无法确定冻结哪条库存行直接阻断
@@ -492,6 +539,8 @@ public class ReservationStockOutOrderDomainService {
} }
//设置物料信息 //设置物料信息
setMaterialDetailInfo(stockOutOrderDO); setMaterialDetailInfo(stockOutOrderDO);
// 明细行冗余存储库存锁定模式编辑时按当前行仓库重算幂等未冻结单的仓库模式可能已切换
fillDetailStockLockMode(stockOutOrderDO);
// 下单冻结模式编辑重锁原子先WMS侧释放原冻结+按新明细重锁同一事务成功后才改本地 // 下单冻结模式编辑重锁原子先WMS侧释放原冻结+按新明细重锁同一事务成功后才改本地
// 已下发WMS的冻结单不可编辑须先取消下发判据=活动执行单issueStatus 不可靠 // 已下发WMS的冻结单不可编辑须先取消下发判据=活动执行单issueStatus 不可靠
handleFreezeOnUpdate(stockOutOrderDO, stockInOrderPO); handleFreezeOnUpdate(stockOutOrderDO, stockInOrderPO);
@@ -606,6 +655,8 @@ public class ReservationStockOutOrderDomainService {
reservationOutMaterialDetail.setMaterialBaseInfoId(materialBaseInfoPO.getMaterialBaseInfoId()); reservationOutMaterialDetail.setMaterialBaseInfoId(materialBaseInfoPO.getMaterialBaseInfoId());
reservationOutMaterialDetail.setMaterialCode(materialBaseInfoPO.getMaterialCode()); reservationOutMaterialDetail.setMaterialCode(materialBaseInfoPO.getMaterialCode());
reservationOutMaterialDetail.setMaterialName(materialBaseInfoPO.getMaterialName()); reservationOutMaterialDetail.setMaterialName(materialBaseInfoPO.getMaterialName());
// TZPD 外部推入单不参与下单冻结R8明细库存锁定模式固定为 2-分配库存冻结
reservationOutMaterialDetail.setStockLockMode(2);
return outMaterialDetailService.save(reservationOutMaterialDetail); return outMaterialDetailService.save(reservationOutMaterialDetail);
} }
@@ -876,6 +927,8 @@ public class ReservationStockOutOrderDomainService {
// 按照 warehouseId 分组 // 按照 warehouseId 分组
Map<Long, List<ReservationOutMaterialDetail>> materialDetailGroupByWarehouse = materialDetailList.stream() Map<Long, List<ReservationOutMaterialDetail>> materialDetailGroupByWarehouse = materialDetailList.stream()
.collect(Collectors.groupingBy(ReservationOutMaterialDetail::getWarehouseId)); .collect(Collectors.groupingBy(ReservationOutMaterialDetail::getWarehouseId));
// 各仓执行单的库存锁定模式JSON元素forEach后覆盖回写业务单单头元素带执行单号
List<Map<String, Object>> stockLockModeJsonItems = new ArrayList<>();
materialDetailGroupByWarehouse.forEach((warehouseId, details) -> { materialDetailGroupByWarehouse.forEach((warehouseId, details) -> {
Long topOrgId = reservationStockInOrderMapper.getTopOrgId(warehouseId); Long topOrgId = reservationStockInOrderMapper.getTopOrgId(warehouseId);
Long orgId = reservationStockInOrderMapper.getOrgId(warehouseId); Long orgId = reservationStockInOrderMapper.getOrgId(warehouseId);
@@ -902,6 +955,8 @@ public class ReservationStockOutOrderDomainService {
// reservationStockInOrder.setTopOrganizationId(topOrgId); // reservationStockInOrder.setTopOrganizationId(topOrgId);
reservationStockInOrder.setBusinessOutOrderNumber(inOrderNumber); reservationStockInOrder.setBusinessOutOrderNumber(inOrderNumber);
// 库存锁定模式取该仓明细行首个非空值下单时判定与明细/实际冻结行为一致
reservationStockInOrder.setStockLockMode(details.stream().map(ReservationOutMaterialDetail::getStockLockMode).filter(Objects::nonNull).findFirst().orElse(2));
// reservationStockInOrder.setOutOrderNumber(generateExecutionOrderNumber(warehouseCode)); // reservationStockInOrder.setOutOrderNumber(generateExecutionOrderNumber(warehouseCode));
//设置单号(仓库单号规则: Feign优先, system服务失败/降级时本地跨库兜底) //设置单号(仓库单号规则: Feign优先, system服务失败/降级时本地跨库兜底)
@@ -952,9 +1007,17 @@ public class ReservationStockOutOrderDomainService {
reservationStockInOrder.setQuantity(quantity); reservationStockInOrder.setQuantity(quantity);
executionStockOutOrderService.save(reservationStockInOrder); executionStockOutOrderService.save(reservationStockInOrder);
executionInOrderNumbers.add(reservationStockInOrder.getOutOrderNumber()); executionInOrderNumbers.add(reservationStockInOrder.getOutOrderNumber());
Map<String, Object> lockModeItem = new LinkedHashMap<>();
lockModeItem.put("executionOrderNumber", reservationStockInOrder.getOutOrderNumber());
lockModeItem.put("warehouseCode", reservationStockInOrder.getWarehouseCode());
lockModeItem.put("warehouseName", reservationStockInOrder.getWarehouseName());
lockModeItem.put("stockLockMode", reservationStockInOrder.getStockLockMode());
stockLockModeJsonItems.add(lockModeItem);
executionOutMaterialDetailService.saveBatch(inMaterialDetailList); executionOutMaterialDetailService.saveBatch(inMaterialDetailList);
}); });
byId.setExecutionOutOrderNumber(String.join(",", executionInOrderNumbers)); byId.setExecutionOutOrderNumber(String.join(",", executionInOrderNumbers));
// 单头库存锁定模式JSON覆盖为执行单级元素带执行单号
byId.setStockLockModeJson(JSON.toJSONString(stockLockModeJsonItems));
stockOutOrderService.updateById(byId); stockOutOrderService.updateById(byId);
} }
return update; return update;
@@ -1224,6 +1287,8 @@ public class ReservationStockOutOrderDomainService {
} }
List<String> executionInOrderNumbers = new ArrayList<>(); List<String> executionInOrderNumbers = new ArrayList<>();
// 各仓执行单的库存锁定模式JSON元素forEach后覆盖回写业务单单头元素带执行单号
List<Map<String, Object>> stockLockModeJsonItems = new ArrayList<>();
materialDetailGroupByWarehouse.forEach((warehouseId, details) -> { materialDetailGroupByWarehouse.forEach((warehouseId, details) -> {
if (warehouseId == null) warehouseId = warehouseId1; if (warehouseId == null) warehouseId = warehouseId1;
Long topOrgId = reservationStockInOrderMapper.getTopOrgId(warehouseId); Long topOrgId = reservationStockInOrderMapper.getTopOrgId(warehouseId);
@@ -1248,6 +1313,8 @@ public class ReservationStockOutOrderDomainService {
reservationStockInOrder.setWarehouseCode(warehouseCode); reservationStockInOrder.setWarehouseCode(warehouseCode);
reservationStockInOrder.setWarehouseName(warehouseName); reservationStockInOrder.setWarehouseName(warehouseName);
reservationStockInOrder.setBusinessOutOrderNumber(inOrderNumber); reservationStockInOrder.setBusinessOutOrderNumber(inOrderNumber);
// 库存锁定模式取该仓明细行首个非空值下单时判定与明细/实际冻结行为一致
reservationStockInOrder.setStockLockMode(details.stream().map(ReservationOutMaterialDetail::getStockLockMode).filter(Objects::nonNull).findFirst().orElse(2));
//设置单号(仓库单号规则: Feign优先, system服务失败/降级时本地跨库兜底) //设置单号(仓库单号规则: Feign优先, system服务失败/降级时本地跨库兜底)
@@ -1296,6 +1363,12 @@ public class ReservationStockOutOrderDomainService {
BigDecimal quantity = details.stream().map(ReservationOutMaterialDetail::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add); BigDecimal quantity = details.stream().map(ReservationOutMaterialDetail::getQuantity).filter(Objects::nonNull).reduce(BigDecimal.ZERO, BigDecimal::add);
reservationStockInOrder.setQuantity(quantity); reservationStockInOrder.setQuantity(quantity);
executionInOrderNumbers.add(reservationStockInOrder.getOutOrderNumber()); executionInOrderNumbers.add(reservationStockInOrder.getOutOrderNumber());
Map<String, Object> lockModeItem = new LinkedHashMap<>();
lockModeItem.put("executionOrderNumber", reservationStockInOrder.getOutOrderNumber());
lockModeItem.put("warehouseCode", reservationStockInOrder.getWarehouseCode());
lockModeItem.put("warehouseName", reservationStockInOrder.getWarehouseName());
lockModeItem.put("stockLockMode", reservationStockInOrder.getStockLockMode());
stockLockModeJsonItems.add(lockModeItem);
executionStockOutOrderService.save(reservationStockInOrder); executionStockOutOrderService.save(reservationStockInOrder);
executionOutMaterialDetailService.saveBatch(inMaterialDetailList); executionOutMaterialDetailService.saveBatch(inMaterialDetailList);
@@ -1308,6 +1381,8 @@ public class ReservationStockOutOrderDomainService {
stockOutOrderApplicationService.issueOrder(param); stockOutOrderApplicationService.issueOrder(param);
}); });
byId.setExecutionOutOrderNumber(String.join(",", executionInOrderNumbers)); byId.setExecutionOutOrderNumber(String.join(",", executionInOrderNumbers));
// 单头库存锁定模式JSON覆盖为执行单级元素带执行单号
byId.setStockLockModeJson(JSON.toJSONString(stockLockModeJsonItems));
stockOutOrderService.updateById(byId); stockOutOrderService.updateById(byId);
} }
return update; return update;
@@ -431,6 +431,13 @@ public class ReserveStockOutOrderDomainService {
Long shipperId = reservationStockOutOrder.getShipperId(); Long shipperId = reservationStockOutOrder.getShipperId();
String jsbz = reservationStockInOrderMapper.getJsbz(shipperId); String jsbz = reservationStockInOrderMapper.getJsbz(shipperId);
reservationStockOutOrder.setSettlementCurrency(jsbz); reservationStockOutOrder.setSettlementCurrency(jsbz);
// 单头库存锁定模式JSON老预约单下发的业务单不走下单冻结钩子WMS分配时才冻结固定 2-分配库存冻结单仓单元素
Map<String, Object> stockLockModeItem = new LinkedHashMap<>();
stockLockModeItem.put("warehouseId", reservationStockOutOrder.getWarehouseId());
stockLockModeItem.put("warehouseCode", reservationStockOutOrder.getWarehouseCode());
stockLockModeItem.put("warehouseName", reservationStockOutOrder.getWarehouseName());
stockLockModeItem.put("stockLockMode", 2);
reservationStockOutOrder.setStockLockModeJson(JSON.toJSONString(java.util.Collections.singletonList(stockLockModeItem)));
// 保留旧单号用于查询源明细数据 // 保留旧单号用于查询源明细数据
String oldOutOrderNumber = reservationStockOutOrder.getOutOrderNumber(); String oldOutOrderNumber = reservationStockOutOrder.getOutOrderNumber();
// 生成出库业务单号防止与已生成的出库业务单号重复 // 生成出库业务单号防止与已生成的出库业务单号重复
@@ -445,6 +452,8 @@ public class ReserveStockOutOrderDomainService {
ReservationOutMaterialDetail reservationOutMaterialDetail = new ReservationOutMaterialDetail(); ReservationOutMaterialDetail reservationOutMaterialDetail = new ReservationOutMaterialDetail();
BeanUtils.copyProperties(reserveOutMaterialDetail, reservationOutMaterialDetail,"materialDetailId"); BeanUtils.copyProperties(reserveOutMaterialDetail, reservationOutMaterialDetail,"materialDetailId");
// reservationOutMaterialDetail.setOutOrderNumber(newOrderNumber); // 使用新单号保持与主表关联 // reservationOutMaterialDetail.setOutOrderNumber(newOrderNumber); // 使用新单号保持与主表关联
// 老预约单下发生成的业务单不走下单冻结钩子客户预约单在WMS分配时才冻结明细模式固定为 2-分配库存冻结
reservationOutMaterialDetail.setStockLockMode(2);
String lot = generateDateSerialNumber(); String lot = generateDateSerialNumber();
lot = lot+"-"+index; lot = lot+"-"+index;
index++; index++;
@@ -32,6 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="serialNumberManage" column="serial_number_manage" /> <result property="serialNumberManage" column="serial_number_manage" />
<result property="materialInventoryId" column="material_inventory_id" /> <result property="materialInventoryId" column="material_inventory_id" />
<result property="warehouseId" column="warehouse_id" /> <result property="warehouseId" column="warehouse_id" />
<result property="stockLockMode" column="stock_lock_mode" />
<result property="warehouseCode" column="warehouse_code" /> <result property="warehouseCode" column="warehouse_code" />
<result property="warehouseName" column="warehouse_name" /> <result property="warehouseName" column="warehouse_name" />
<result property="storageSectionId" column="storage_section_id" /> <result property="storageSectionId" column="storage_section_id" />
@@ -119,7 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.out_order_number, a.material_base_info_id, a.line_number, a.material_code, a.material_name, a.bar_code, a.weight_limit, a.volume_limit, a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.out_order_number, a.material_base_info_id, a.line_number, a.material_code, a.material_name, a.bar_code, a.weight_limit, a.volume_limit,
a.quantity, a.already_allocation_quantity, a.allocation_quantity, a.picking_quantity, a.check_quantity, ROUND(GREATEST(0, IFNULL(a.quantity, 0) - IFNULL(a.check_quantity, 0), IFNULL(a.picking_quantity, 0) - IFNULL(a.check_quantity, 0)), 2) AS wait_check_quantity, a.quantity, a.already_allocation_quantity, a.allocation_quantity, a.picking_quantity, a.check_quantity, ROUND(GREATEST(0, IFNULL(a.quantity, 0) - IFNULL(a.check_quantity, 0), IFNULL(a.picking_quantity, 0) - IFNULL(a.check_quantity, 0)), 2) AS wait_check_quantity,
a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage, a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage,
a.warehouse_id, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify, a.warehouse_id, a.stock_lock_mode, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify,
a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name, a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name,
a.remark, a.create_time, a.create_by,gen_picking_order, a.remark, a.create_time, a.create_by,gen_picking_order,
a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type,
@@ -477,7 +478,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name,
a.material_warehouse_control_id, a.serial_number_manage, a.material_warehouse_control_id, a.serial_number_manage,
a.material_inventory_id, a.batch_number, a.material_inventory_id, a.batch_number,
a.warehouse_id, a.warehouse_code, a.warehouse_name, a.warehouse_id, a.stock_lock_mode, a.warehouse_code, a.warehouse_name,
a.storage_section_id, a.storage_code, a.storage_name, a.storage_section_id, a.storage_code, a.storage_name,
a.storage_location_id, a.storage_location_code, a.storage_location_name, a.storage_location_id, a.storage_location_code, a.storage_location_name,
a.level, a.parent_unique_id, a.allow_modify, a.level, a.parent_unique_id, a.allow_modify,
@@ -53,6 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateByName" column="update_by_name" /> <result property="updateByName" column="update_by_name" />
<result property="delFlag" column="del_flag" /> <result property="delFlag" column="del_flag" />
<result property="reverseFlag" column="reverse_flag" /> <result property="reverseFlag" column="reverse_flag" />
<result property="stockLockMode" column="stock_lock_mode" />
<result property="overStockId" column="over_stock_id" /> <result property="overStockId" column="over_stock_id" />
<result property="overStockStatus" column="over_stock_status" /> <result property="overStockStatus" column="over_stock_status" />
<result property="overStockType" column="over_stock_type" /> <result property="overStockType" column="over_stock_type" />
@@ -129,7 +130,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.cancel_time, a.close_order, a.close_remark, a.close_by, a.close_by_name, a.close_time, a.check_status,a.BUSINESS_ORDER_NO, a.cancel_time, a.close_order, a.close_remark, a.close_by, a.close_by_name, a.close_time, a.check_status,a.BUSINESS_ORDER_NO,
a.check_task_distribution, a.check_task_distribution_time, a.check_operators_by, a.check_operators_name, a.mobilize_code, a.check_task_distribution, a.check_task_distribution_time, a.check_operators_by, a.check_operators_name, a.mobilize_code,
a.remark, a.create_time, a.create_by, a.create_by_name,a.business_number,a.train_no,a.amount,a.business_out_order_number, a.remark, a.create_time, a.create_by, a.create_by_name,a.business_number,a.train_no,a.amount,a.business_out_order_number,
a.update_time, a.update_by, a.update_by_name, a.del_flag, a.reverse_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type,a."TO", a.update_time, a.update_by, a.update_by_name, a.del_flag, a.reverse_flag, a.stock_lock_mode, a.over_stock_id, a.over_stock_status, a.over_stock_type,a."TO",
a.CONTACT_PERSON,a.VEHICLE_MODEL_PLATE,a.ENTRUST_NO,a.TEL,a.DRIVER_SIGN,a.FAX,a.DECLARE_CUSTOMS,a.MANUFACTURER, a.CONTACT_PERSON,a.VEHICLE_MODEL_PLATE,a.ENTRUST_NO,a.TEL,a.DRIVER_SIGN,a.FAX,a.DECLARE_CUSTOMS,a.MANUFACTURER,
a.CUSTOMS_DECLARER_INFO,a.DELIVERY_ADDR,a.ENTRY_EXIT_CUSTOMS,a.DEPARTURE_ARRIVAL_COUNTRY,a.CARRIER,a.CONTAINER_NO,a.CONTAINER_NO_NAME,a.OUTBOUND_DATE, a.CUSTOMS_DECLARER_INFO,a.DELIVERY_ADDR,a.ENTRY_EXIT_CUSTOMS,a.DEPARTURE_ARRIVAL_COUNTRY,a.CARRIER,a.CONTAINER_NO,a.CONTAINER_NO_NAME,a.OUTBOUND_DATE,
a.COMPLETE_TIME,a.ORDER_DATE,a.TRANSPORT_MODE_CODE,a.TRANSPORT_MODE_NAME,a.SUPERVISION_MODE_CODE,a.SUPERVISION_MODE_NAME, a.COMPLETE_TIME,a.ORDER_DATE,a.TRANSPORT_MODE_CODE,a.TRANSPORT_MODE_NAME,a.SUPERVISION_MODE_CODE,a.SUPERVISION_MODE_NAME,
@@ -32,6 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="serialNumberManage" column="serial_number_manage" /> <result property="serialNumberManage" column="serial_number_manage" />
<result property="materialInventoryId" column="material_inventory_id" /> <result property="materialInventoryId" column="material_inventory_id" />
<result property="warehouseId" column="warehouse_id" /> <result property="warehouseId" column="warehouse_id" />
<result property="stockLockMode" column="stock_lock_mode" />
<result property="warehouseCode" column="warehouse_code" /> <result property="warehouseCode" column="warehouse_code" />
<result property="warehouseName" column="warehouse_name" /> <result property="warehouseName" column="warehouse_name" />
<result property="storageSectionId" column="storage_section_id" /> <result property="storageSectionId" column="storage_section_id" />
@@ -121,7 +122,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.out_order_number, a.material_base_info_id, a.line_number, a.material_code, a.material_name, a.bar_code, a.weight_limit, a.volume_limit, a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.out_order_number, a.material_base_info_id, a.line_number, a.material_code, a.material_name, a.bar_code, a.weight_limit, a.volume_limit,
a.quantity, a.already_allocation_quantity, a.allocation_quantity, a.picking_quantity, a.check_quantity, ROUND(GREATEST(0, IFNULL(a.quantity, 0) - IFNULL(a.check_quantity, 0), IFNULL(a.picking_quantity, 0) - IFNULL(a.check_quantity, 0)), 2) AS wait_check_quantity, a.quantity, a.already_allocation_quantity, a.allocation_quantity, a.picking_quantity, a.check_quantity, ROUND(GREATEST(0, IFNULL(a.quantity, 0) - IFNULL(a.check_quantity, 0), IFNULL(a.picking_quantity, 0) - IFNULL(a.check_quantity, 0)), 2) AS wait_check_quantity,
a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage, a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage,
a.warehouse_id, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify, a.warehouse_id, a.stock_lock_mode, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify,
a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name, a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name,
a.remark, a.create_time, a.create_by,gen_picking_order, a.remark, a.create_time, a.create_by,gen_picking_order,
a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type,
@@ -118,6 +118,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="discount" column="DISCOUNT" /> <result property="discount" column="DISCOUNT" />
<result property="totalOutboundQuantity" column="TOTAL_OUTBOUND_QUANTITY" /> <result property="totalOutboundQuantity" column="TOTAL_OUTBOUND_QUANTITY" />
<result property="reverseStatus" column="REVERSE_STATUS" /> <result property="reverseStatus" column="REVERSE_STATUS" />
<result property="stockLockModeJson" column="STOCK_LOCK_MODE_JSON" />
<result property="reverseBy" column="REVERSE_BY" /> <result property="reverseBy" column="REVERSE_BY" />
<result property="reverseByName" column="REVERSE_BY_NAME" /> <result property="reverseByName" column="REVERSE_BY_NAME" />
<result property="reverseTime" column="REVERSE_TIME" /> <result property="reverseTime" column="REVERSE_TIME" />
@@ -142,7 +143,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.DIRECTOR_NAME ,a.DIRECTOR_PHONE,a.DIRECTOR_ID,a.RESERVATION_ORDER_SOURCE,a.OUTBOUND_TIME,a.RETURN_QUANTITY,a.DELIVERY_NAME,a.CUSTOMER_NUMBER,a.INVOICE_NUMBER,a.RETURN_ORDER_NUMBER,a.TOTAL_AMOUNT, a.DIRECTOR_NAME ,a.DIRECTOR_PHONE,a.DIRECTOR_ID,a.RESERVATION_ORDER_SOURCE,a.OUTBOUND_TIME,a.RETURN_QUANTITY,a.DELIVERY_NAME,a.CUSTOMER_NUMBER,a.INVOICE_NUMBER,a.RETURN_ORDER_NUMBER,a.TOTAL_AMOUNT,
a.ROUTE,a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME,a.execution_out_order_number,a.LINE_CODE,a.LINE_NAME,a.SHUTTLE_NO, a.ROUTE,a.PUSH_TIME,a.PUSH_STATUS,a.PUSH_BY,a.PUSH_BY_NAME,a.execution_out_order_number,a.LINE_CODE,a.LINE_NAME,a.SHUTTLE_NO,
a.TOTAL_WAREHOUSE_RENT,a.BUSINESS_CHARGE_TYPE,a.BUSINESS_PRICE_WAY,a.DISCOUNT, a.TOTAL_WAREHOUSE_RENT,a.BUSINESS_CHARGE_TYPE,a.BUSINESS_PRICE_WAY,a.DISCOUNT,
a.REVERSE_STATUS,a.REVERSE_BY,a.REVERSE_BY_NAME,a.REVERSE_TIME,a.REVERSE_REMARK a.REVERSE_STATUS,a.REVERSE_BY,a.REVERSE_BY_NAME,a.REVERSE_TIME,a.REVERSE_REMARK,
a.STOCK_LOCK_MODE_JSON
</sql> </sql>
@@ -222,6 +222,8 @@ public class HandoverTaskOrderDomainService {
} }
TaskHandoverMaterialDetailPO detail = new TaskHandoverMaterialDetailPO(); TaskHandoverMaterialDetailPO detail = new TaskHandoverMaterialDetailPO();
detail.setMaterialDetailId(omd.getMaterialDetailId()); detail.setMaterialDetailId(omd.getMaterialDetailId());
// 库存锁定模式回显取自出库单明细
detail.setStockLockMode(omd.getStockLockMode());
detail.setUniqueId(omd.getUniqueId()); detail.setUniqueId(omd.getUniqueId());
detail.setTaskNumber(handoverTaskOrderPO.getTaskNumber()); detail.setTaskNumber(handoverTaskOrderPO.getTaskNumber());
detail.setOrganizationId(omd.getOrganizationId()); detail.setOrganizationId(omd.getOrganizationId());
@@ -306,6 +308,8 @@ public class HandoverTaskOrderDomainService {
} }
TaskHandoverMaterialDetailPO detail = new TaskHandoverMaterialDetailPO(); TaskHandoverMaterialDetailPO detail = new TaskHandoverMaterialDetailPO();
detail.setMaterialDetailId(omd.getMaterialDetailId()); detail.setMaterialDetailId(omd.getMaterialDetailId());
// 库存锁定模式回显取自出库单明细
detail.setStockLockMode(omd.getStockLockMode());
detail.setUniqueId(omd.getUniqueId()); detail.setUniqueId(omd.getUniqueId());
detail.setTaskNumber(handoverTaskOrderPO.getTaskNumber()); detail.setTaskNumber(handoverTaskOrderPO.getTaskNumber());
detail.setOrganizationId(omd.getOrganizationId()); detail.setOrganizationId(omd.getOrganizationId());
@@ -170,6 +170,9 @@ public class OutMaterialDetail extends BaseVOEntity {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), OMS推单复制/WMS自建为2")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -228,6 +228,11 @@ public class OutMaterialDetailImpl extends ServiceImpl<OutMaterialDetailMapper,
outMaterialDetail.setCreateByName(userRealName); outMaterialDetail.setCreateByName(userRealName);
outMaterialDetail.setCreateTime(new Date()); outMaterialDetail.setCreateTime(new Date());
outMaterialDetail.setQuantity(outMaterialDetail.getOutboundQuantity()); outMaterialDetail.setQuantity(outMaterialDetail.getOutboundQuantity());
// 库存锁定模式WMS自建/通知/调拨单不参与下单冻结明细固定 2-分配库存冻结
// OMS推单走 omsOrderAddDetail 直存 saveBatch 不经此处其值随推送携带互不影响
if (outMaterialDetail.getStockLockMode() == null) {
outMaterialDetail.setStockLockMode(2);
}
String materialNo = outMaterialDetail.getMaterialNo(); String materialNo = outMaterialDetail.getMaterialNo();
List<MaterialBaseInfo> materialBaseInfos = materialBaseInfoMapper.selectList(new QueryWrapper<MaterialBaseInfo>().lambda().eq(MaterialBaseInfo::getMaterialCode, materialNo)); List<MaterialBaseInfo> materialBaseInfos = materialBaseInfoMapper.selectList(new QueryWrapper<MaterialBaseInfo>().lambda().eq(MaterialBaseInfo::getMaterialCode, materialNo));
if (!CollectionUtils.isEmpty(materialBaseInfos) && materialBaseInfos.size() > 0) { if (!CollectionUtils.isEmpty(materialBaseInfos) && materialBaseInfos.size() > 0) {
@@ -282,6 +287,10 @@ public class OutMaterialDetailImpl extends ServiceImpl<OutMaterialDetailMapper,
outMaterialDetail.setOrganizationId(outMaterialDetailBaseDO.getOrganizationId()); outMaterialDetail.setOrganizationId(outMaterialDetailBaseDO.getOrganizationId());
outMaterialDetail.setOrganizationName(outMaterialDetailBaseDO.getOrganizationName()); outMaterialDetail.setOrganizationName(outMaterialDetailBaseDO.getOrganizationName());
outMaterialDetail.setTopOrganizationId(outMaterialDetailBaseDO.getTopOrganizationId()); outMaterialDetail.setTopOrganizationId(outMaterialDetailBaseDO.getTopOrganizationId());
// 编辑时新增行未显式带值的固定 2-分配库存冻结已存行不受影响updateById 忽略 null
if (outMaterialDetail.getStockLockMode() == null) {
outMaterialDetail.setStockLockMode(2);
}
}else { }else {
BeanUtils.copyProperties(outMaterialDetailDO, outMaterialDetail); BeanUtils.copyProperties(outMaterialDetailDO, outMaterialDetail);
outMaterialDetail.setUpdateBy(loginUser.getUserid()); outMaterialDetail.setUpdateBy(loginUser.getUserid());
@@ -184,6 +184,9 @@ public class OutMaterialDetailPO extends StockOutOrderBaseDO {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -174,6 +174,9 @@ public class OutMaterialDetailDO extends BaseVOEntity {
@ApiModelProperty("分配仓库id") @ApiModelProperty("分配仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("分配仓库编码") @ApiModelProperty("分配仓库编码")
@Excel(name = "分配仓库编码") @Excel(name = "分配仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -161,6 +161,9 @@ public class PickingMaterialDetail extends BaseVOEntity {
@Excel(name = "仓库id") @Excel(name = "仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 生成时从出库单明细复制")
private Integer stockLockMode;
@ApiModelProperty("仓库编码") @ApiModelProperty("仓库编码")
@Excel(name = "仓库编码") @Excel(name = "仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -170,6 +170,9 @@ public class PickingMaterialDetailPO extends BaseVOEntity {
@Excel(name = "仓库id") @Excel(name = "仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("仓库编码") @ApiModelProperty("仓库编码")
@Excel(name = "仓库编码") @Excel(name = "仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -158,6 +158,9 @@ public class PickingMaterialDetailDO extends BaseVOEntity {
@Excel(name = "仓库id") @Excel(name = "仓库id")
private Long warehouseId; private Long warehouseId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("仓库编码") @ApiModelProperty("仓库编码")
@Excel(name = "仓库编码") @Excel(name = "仓库编码")
private String warehouseCode; private String warehouseCode;
@@ -206,6 +206,8 @@ public class ReviewOrderDomainService {
d.setReviewOrderId(reviewOrderId); d.setReviewOrderId(reviewOrderId);
d.setReviewOrderNumber(reviewOrderNumber); d.setReviewOrderNumber(reviewOrderNumber);
d.setOutOrderNumber(outOrderNumber); d.setOutOrderNumber(outOrderNumber);
// 库存锁定模式随拣货明细取值拣货行未带出时从出库明细兜底
d.setStockLockMode(line.getStockLockMode());
d.setOutUniqueId(line.getOutUniqueId()); d.setOutUniqueId(line.getOutUniqueId());
d.setMaterialBaseInfoId(line.getMaterialBaseInfoId()); d.setMaterialBaseInfoId(line.getMaterialBaseInfoId());
d.setMaterialCode(line.getMaterialCode()); d.setMaterialCode(line.getMaterialCode());
@@ -265,6 +267,10 @@ public class ReviewOrderDomainService {
} }
if (outMd != null) { if (outMd != null) {
d.setMaterialDetailId(outMd.getMaterialDetailId()); d.setMaterialDetailId(outMd.getMaterialDetailId());
// 库存锁定模式拣货明细行未带出时从出库明细兜底
if (d.getStockLockMode() == null) {
d.setStockLockMode(outMd.getStockLockMode());
}
// 物料编码/名称拣货明细行若未落库或未映射出值从出库明细兜底避免复核单复核作业任务明细为空 // 物料编码/名称拣货明细行若未落库或未映射出值从出库明细兜底避免复核单复核作业任务明细为空
if (!StringUtils.hasText(d.getMaterialCode())) { if (!StringUtils.hasText(d.getMaterialCode())) {
d.setMaterialCode(outMd.getMaterialCode()); d.setMaterialCode(outMd.getMaterialCode());
@@ -30,6 +30,9 @@ public class ReviewMaterialDetail extends BaseVOEntity {
private String outOrderNumber; private String outOrderNumber;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 生成时从拣货明细取值")
private Integer stockLockMode;
private Long outUniqueId; private Long outUniqueId;
private Long materialDetailId; private Long materialDetailId;
@@ -31,6 +31,9 @@ public class ReviewMaterialDetailPO extends BaseVOEntity {
@ApiModelProperty("出库单号") @ApiModelProperty("出库单号")
private String outOrderNumber; private String outOrderNumber;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认)")
private Integer stockLockMode;
@ApiModelProperty("出库明细 unique_id") @ApiModelProperty("出库明细 unique_id")
private Long outUniqueId; private Long outUniqueId;
@@ -26,6 +26,9 @@ public class TaskHandoverMaterialDetailPO extends BaseVOEntity {
@ApiModelProperty("出库单物料明细id") @ApiModelProperty("出库单物料明细id")
private Long materialDetailId; private Long materialDetailId;
@ApiModelProperty("库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 回显时取自出库单明细")
private Integer stockLockMode;
@ApiModelProperty("组织表ID") @ApiModelProperty("组织表ID")
@Excel(name = "组织表ID") @Excel(name = "组织表ID")
private Long organizationId; private Long organizationId;
@@ -32,6 +32,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="serialNumberManage" column="serial_number_manage" /> <result property="serialNumberManage" column="serial_number_manage" />
<result property="materialInventoryId" column="material_inventory_id" /> <result property="materialInventoryId" column="material_inventory_id" />
<result property="warehouseId" column="warehouse_id" /> <result property="warehouseId" column="warehouse_id" />
<result property="stockLockMode" column="stock_lock_mode" />
<result property="warehouseCode" column="warehouse_code" /> <result property="warehouseCode" column="warehouse_code" />
<result property="warehouseName" column="warehouse_name" /> <result property="warehouseName" column="warehouse_name" />
<result property="storageSectionId" column="storage_section_id" /> <result property="storageSectionId" column="storage_section_id" />
@@ -125,7 +126,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.out_order_number, a.material_base_info_id, a.line_number, a.material_code, a.material_name, a.bar_code, a.weight_limit, a.volume_limit, a.material_detail_id, a.organization_id, a.organization_name, a.top_organization_id, a.unique_id, a.out_order_number, a.material_base_info_id, a.line_number, a.material_code, a.material_name, a.bar_code, a.weight_limit, a.volume_limit,
a.quantity, a.already_allocation_quantity, a.allocation_quantity, a.picking_quantity, a.check_quantity, ROUND(GREATEST(0, IFNULL(a.quantity, 0) - IFNULL(a.check_quantity, 0), IFNULL(a.picking_quantity, 0) - IFNULL(a.check_quantity, 0)), 2) AS wait_check_quantity, a.quantity, a.already_allocation_quantity, a.allocation_quantity, a.picking_quantity, a.check_quantity, ROUND(GREATEST(0, IFNULL(a.quantity, 0) - IFNULL(a.check_quantity, 0), IFNULL(a.picking_quantity, 0) - IFNULL(a.check_quantity, 0)), 2) AS wait_check_quantity,
a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage, a.pack_id, a.pack_code, a.pack_name, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage,
a.warehouse_id, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify, a.warehouse_id, a.stock_lock_mode, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.level, a.parent_unique_id, a.allow_modify,
a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name, a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name,
a.remark, a.create_time, a.create_by,gen_picking_order, a.remark, a.create_time, a.create_by,gen_picking_order,
a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type, a.create_by_name, a.update_time, a.update_by, a.update_by_name, a.del_flag, a.over_stock_id, a.over_stock_status, a.over_stock_type,
@@ -31,6 +31,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="materialWarehouseControlId" column="material_warehouse_control_id" /> <result property="materialWarehouseControlId" column="material_warehouse_control_id" />
<result property="serialNumberManage" column="serial_number_manage" /> <result property="serialNumberManage" column="serial_number_manage" />
<result property="warehouseId" column="warehouse_id" /> <result property="warehouseId" column="warehouse_id" />
<result property="stockLockMode" column="stock_lock_mode" />
<result property="warehouseCode" column="warehouse_code" /> <result property="warehouseCode" column="warehouse_code" />
<result property="warehouseName" column="warehouse_name" /> <result property="warehouseName" column="warehouse_name" />
<result property="storageSectionId" column="storage_section_id" /> <result property="storageSectionId" column="storage_section_id" />
@@ -91,7 +92,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.volume_limit, a.quantity, a.picking_quantity, a.pack_id, a.pack_code, a.pack_name, a.volume_limit, a.quantity, a.picking_quantity, a.pack_id, a.pack_code, a.pack_name,
a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage, a.pack_detail_id, a.unit_code, a.unit_name, a.material_warehouse_control_id, a.serial_number_manage,
a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name, a.material_inventory_id, a.batch_number, a.container_id, a.container_code, a.container_type, a.container_type_name, a.material_status_code, a.material_status_name,
a.warehouse_id, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name, a.warehouse_id, a.stock_lock_mode, a.warehouse_code, a.warehouse_name, a.storage_section_id, a.storage_code, a.storage_name,
a.storage_location_id, a.storage_location_code, a.storage_location_name, a.remark, a.storage_location_id, a.storage_location_code, a.storage_location_name, a.remark,
a.BATCH_REF_NO, a.SHEET_REF_NO, a.BOX_PALLET_NO, a.EXT_ATTR_1, a.EXT_ATTR_2, a.BATCH_REF_NO, a.SHEET_REF_NO, a.BOX_PALLET_NO, a.EXT_ATTR_1, a.EXT_ATTR_2,
a.PRODUCTION_DATE, a.EXPIRY_DATE, a.INVENTORY_DATE, a.EXT_ATTR_3, a.EXT_ATTR_4, a.PRODUCTION_DATE, a.EXPIRY_DATE, a.INVENTORY_DATE, a.EXT_ATTR_3, a.EXT_ATTR_4,
@@ -43,6 +43,7 @@
<result property="reviewOrderId" column="review_order_id"/> <result property="reviewOrderId" column="review_order_id"/>
<result property="reviewOrderNumber" column="review_order_number"/> <result property="reviewOrderNumber" column="review_order_number"/>
<result property="outOrderNumber" column="out_order_number"/> <result property="outOrderNumber" column="out_order_number"/>
<result property="stockLockMode" column="stock_lock_mode"/>
<result property="outUniqueId" column="out_unique_id"/> <result property="outUniqueId" column="out_unique_id"/>
<result property="materialDetailId" column="material_detail_id"/> <result property="materialDetailId" column="material_detail_id"/>
<result property="materialBaseInfoId" column="material_base_info_id"/> <result property="materialBaseInfoId" column="material_base_info_id"/>
@@ -268,6 +269,7 @@
d.review_order_id, d.review_order_id,
d.review_order_number, d.review_order_number,
d.out_order_number, d.out_order_number,
d.stock_lock_mode,
d.out_unique_id, d.out_unique_id,
d.material_detail_id, d.material_detail_id,
d.material_base_info_id, d.material_base_info_id,
@@ -446,6 +446,7 @@
SELECT b.lot_no, SELECT b.lot_no,
b.warehouse_code, b.warehouse_code,
b.warehouse_name, b.warehouse_name,
b.stock_lock_mode,
b.material_name, b.material_name,
b.storage_location_name, b.storage_location_name,
b.storage_location_code, b.storage_location_code,
@@ -474,6 +475,7 @@
<result property="specificationModel" column="specification_model"/> <result property="specificationModel" column="specification_model"/>
<result property="quantity" column="quantity"/> <result property="quantity" column="quantity"/>
<result property="warehouseId" column="warehouse_id"/> <result property="warehouseId" column="warehouse_id"/>
<result property="stockLockMode" column="stock_lock_mode"/>
<result property="materialBaseInfoId" column="material_base_info_id"/> <result property="materialBaseInfoId" column="material_base_info_id"/>
<result property="copyCode" column="copy_code"/> <result property="copyCode" column="copy_code"/>
<result property="outboundQuantity" column="outbound_quantity"/> <result property="outboundQuantity" column="outbound_quantity"/>
@@ -516,6 +518,7 @@
b.warehouse_code, b.warehouse_code,
b.warehouse_name, b.warehouse_name,
b.warehouse_id, b.warehouse_id,
b.stock_lock_mode,
b.storage_location_name, b.storage_location_name,
b.lot_no, b.lot_no,
b.piece_count, b.piece_count,
@@ -0,0 +1,78 @@
-- =====================================================================
-- 出库全链路物料明细增加"库存锁定模式"字段 —— 存储与回显
-- 日期: 2026-09-14
-- 数据库: 达梦(DM), 兼容 Oracle 语法
-- 背景:
-- OMS下单冻结库存(防超卖)功能按仓库级开关 stock_lock_mode 生效,
-- 为让前端在单仓/多仓模式下按明细行回显"该行是下单冻结还是分配冻结",
-- 在出库链路各级物料明细上冗余存储库存锁定模式:
-- 1-下单冻结(OMS出库业务单「下单」即冻结WMS库存)
-- 2-分配库存冻结(默认, WMS「分配库存」时才冻结)
-- 取值链:
-- OMS业务单明细 = 保存时按行仓库(行warehouseId优先,空取单头)实时判定;
-- OMS执行单明细 = 下发时从业务单明细复制;
-- WMS出库单明细 = OMS推单时从执行单明细复制(推单参数同步加字段),
-- WMS自建/通知/调拨单 = 2;
-- WMS拣货明细 = 生成时从出库单明细复制;
-- WMS复核明细 = 生成时从拣货明细取值;
-- 交接单明细 = 回显时内存组装取自出库单明细(无明细表,不需要加列)。
-- 兼容: 存量行由 DEFAULT 填 2(执行后可核查, 未填的行按 NULL 视同 2 语义兜底)。
-- 执行位置:
-- 第一、二节在 OMS 库(模式 NGWL_TEST_OMS)执行;
-- 第三、四、五节在 WMS 库(模式 NGWL_TEST_WMS)执行;
-- 生产环境按实际模式名替换。
-- =====================================================================
-- ============ 一、OMS 出库业务单明细 RESERVATION_OUT_MATERIAL_DETAIL ============
ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_OUT_MATERIAL_DETAIL" ADD COLUMN STOCK_LOCK_MODE TINYINT DEFAULT 2;
COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_OUT_MATERIAL_DETAIL".STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 保存时按行仓库判定';
-- ============ 二、OMS 出库执行单明细 EXECUTION_OUT_MATERIAL_DETAIL ============
ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_OUT_MATERIAL_DETAIL" ADD COLUMN STOCK_LOCK_MODE TINYINT DEFAULT 2;
COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_OUT_MATERIAL_DETAIL".STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 下发时从业务单明细复制';
-- ============ 三、WMS 出库明细 OUT_MATERIAL_DETAIL ============
ALTER TABLE "NGWL_TEST_WMS"."OUT_MATERIAL_DETAIL" ADD COLUMN STOCK_LOCK_MODE TINYINT DEFAULT 2;
COMMENT ON COLUMN "NGWL_TEST_WMS"."OUT_MATERIAL_DETAIL".STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), OMS推单复制/WMS自建为2';
-- ============ 四、WMS 拣货明细 PICKING_MATERIAL_DETAIL ============
ALTER TABLE "NGWL_TEST_WMS"."PICKING_MATERIAL_DETAIL" ADD COLUMN STOCK_LOCK_MODE TINYINT DEFAULT 2;
COMMENT ON COLUMN "NGWL_TEST_WMS"."PICKING_MATERIAL_DETAIL".STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 生成时从出库单明细复制';
-- ============ 五、WMS 复核明细 REVIEW_MATERIAL_DETAIL ============
ALTER TABLE "NGWL_TEST_WMS"."REVIEW_MATERIAL_DETAIL" ADD COLUMN STOCK_LOCK_MODE TINYINT DEFAULT 2;
COMMENT ON COLUMN "NGWL_TEST_WMS"."REVIEW_MATERIAL_DETAIL".STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 生成时从拣货明细取值';
-- ============ 六、OMS 出库业务单头 RESERVATION_STOCK_OUT_ORDER ============
-- 多仓单会按仓拆多条执行单, 单头用 JSON 数组存各仓/各执行单的模式; 下单按仓写入, 下发后覆盖为带执行单号
ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" ADD COLUMN STOCK_LOCK_MODE_JSON VARCHAR(2000);
COMMENT ON COLUMN "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER".STOCK_LOCK_MODE_JSON IS '库存锁定模式JSON(多仓多执行单): [{"executionOrderNumber":"CK001","warehouseCode":"QZ","warehouseName":"青洲仓","stockLockMode":1}]; 下单按仓写入, 下发后回填执行单号';
-- ============ 七、OMS 出库执行单头 EXECUTION_STOCK_OUT_ORDER ============
-- 执行单按仓拆分, 整单同仓同模式, 存单值; 下发时从该仓明细行取值(与明细/实际冻结行为一致)
ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_OUT_ORDER" ADD COLUMN STOCK_LOCK_MODE TINYINT DEFAULT 2;
COMMENT ON COLUMN "NGWL_TEST_OMS"."EXECUTION_STOCK_OUT_ORDER".STOCK_LOCK_MODE IS '库存锁定模式: 1-下单冻结 2-分配库存冻结(默认), 下发时按该仓明细行取值';
-- ============ 执行后验证(可选) ============
-- OMS 库执行:
-- SELECT COLUMN_NAME, DATA_TYPE, DATA_DEFAULT FROM ALL_TAB_COLUMNS
-- WHERE OWNER='NGWL_TEST_OMS' AND COLUMN_NAME='STOCK_LOCK_MODE'
-- AND TABLE_NAME IN ('RESERVATION_OUT_MATERIAL_DETAIL','EXECUTION_OUT_MATERIAL_DETAIL','EXECUTION_STOCK_OUT_ORDER');
-- SELECT COLUMN_NAME, DATA_TYPE FROM ALL_TAB_COLUMNS
-- WHERE OWNER='NGWL_TEST_OMS' AND COLUMN_NAME='STOCK_LOCK_MODE_JSON'
-- AND TABLE_NAME = 'RESERVATION_STOCK_OUT_ORDER';
-- WMS 库执行:
-- SELECT COLUMN_NAME, DATA_TYPE, DATA_DEFAULT FROM ALL_TAB_COLUMNS
-- WHERE OWNER='NGWL_TEST_WMS' AND COLUMN_NAME='STOCK_LOCK_MODE'
-- AND TABLE_NAME IN ('OUT_MATERIAL_DETAIL','PICKING_MATERIAL_DETAIL','REVIEW_MATERIAL_DETAIL');
-- ============ 回滚(如需) ============
-- OMS 库:
-- ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_OUT_MATERIAL_DETAIL" DROP COLUMN STOCK_LOCK_MODE;
-- ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_OUT_MATERIAL_DETAIL" DROP COLUMN STOCK_LOCK_MODE;
-- ALTER TABLE "NGWL_TEST_OMS"."RESERVATION_STOCK_OUT_ORDER" DROP COLUMN STOCK_LOCK_MODE_JSON;
-- ALTER TABLE "NGWL_TEST_OMS"."EXECUTION_STOCK_OUT_ORDER" DROP COLUMN STOCK_LOCK_MODE;
-- WMS 库:
-- ALTER TABLE "NGWL_TEST_WMS"."OUT_MATERIAL_DETAIL" DROP COLUMN STOCK_LOCK_MODE;
-- ALTER TABLE "NGWL_TEST_WMS"."PICKING_MATERIAL_DETAIL" DROP COLUMN STOCK_LOCK_MODE;
-- ALTER TABLE "NGWL_TEST_WMS"."REVIEW_MATERIAL_DETAIL" DROP COLUMN STOCK_LOCK_MODE;