feat(wms): 添加钢卷库位分配校验功能
- 实现了实际库位占用状态校验逻辑 - 添加了三级库位拆分状态检查机制 - 实现了四级库位父子层级关系验证 - 在钢卷新增操作中集成库位校验 - 在钢卷修改操作中集成库位校验 - 在钢卷分卷操作中对子卷库位进行校验 - 在钢卷合卷操作中对目标库位进行校验 - 支持忽略同库位重复占用校验的特殊场景
This commit is contained in:
@@ -375,6 +375,11 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 仅查询废品:质量状态为 D+、D、D-
|
||||||
|
if (Boolean.TRUE.equals(bo.getOnlyScrap())) {
|
||||||
|
qw.in("mc.quality_status", java.util.Arrays.asList("D+", "D", "D-"));
|
||||||
|
}
|
||||||
|
|
||||||
// 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN
|
// 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN
|
||||||
boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType());
|
boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType());
|
||||||
boolean hasAnyItemFilter = StringUtils.isNotBlank(bo.getItemMaterial())
|
boolean hasAnyItemFilter = StringUtils.isNotBlank(bo.getItemMaterial())
|
||||||
@@ -624,6 +629,48 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
// 一级库位或其他类型:返回自身ID
|
// 一级库位或其他类型:返回自身ID
|
||||||
return Collections.singletonList(actualWarehouseId);
|
return Collections.singletonList(actualWarehouseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验实际库位是否可用于分配给钢卷:
|
||||||
|
* - 若库位被占用(isEnabled=0)则禁止(除非本次操作是继续使用同一已占用库位的场景,可通过 ignoreOccupiedId 放行占用校验)。
|
||||||
|
* - 若为三级库位且已拆分(splitStatus=1),禁止直接在三级库位上新增/修改。
|
||||||
|
* - 若为四级库位,且其父级三级库位未拆分(splitStatus!=1),禁止使用该四级库位。
|
||||||
|
*/
|
||||||
|
private void validateActualWarehouseForAssign(Long actualWarehouseId, Long ignoreOccupiedId) {
|
||||||
|
if (actualWarehouseId == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
WmsActualWarehouseVo aw = actualWarehouseService.queryById(actualWarehouseId);
|
||||||
|
if (aw == null) {
|
||||||
|
throw new RuntimeException("实际库区不存在");
|
||||||
|
}
|
||||||
|
// 占用校验(isEnabled=0 视为已被占用)
|
||||||
|
if (aw.getIsEnabled() != null && aw.getIsEnabled() == 0
|
||||||
|
&& (ignoreOccupiedId == null || !actualWarehouseId.equals(ignoreOccupiedId))) {
|
||||||
|
throw new RuntimeException("实际库区已被占用,请选择其他库区");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long type = aw.getActualWarehouseType();
|
||||||
|
Integer splitStatus = aw.getSplitStatus();
|
||||||
|
// 三级库位且已拆分,禁止直接在三级层级使用
|
||||||
|
if (type != null && type == 3L && splitStatus != null && splitStatus == 1) {
|
||||||
|
throw new RuntimeException("该库位已被拆分,刷新后重试");
|
||||||
|
}
|
||||||
|
// 四级库位:父级必须是已拆分的三级库位
|
||||||
|
if (type != null && type == 4L) {
|
||||||
|
Long parentId = aw.getParentId();
|
||||||
|
if (parentId != null) {
|
||||||
|
WmsActualWarehouseVo parent = actualWarehouseService.queryById(parentId);
|
||||||
|
if (parent != null) {
|
||||||
|
Integer pSplit = parent.getSplitStatus();
|
||||||
|
Long pType = parent.getActualWarehouseType();
|
||||||
|
if (pType != null && pType == 3L && (pSplit == null || pSplit != 1)) {
|
||||||
|
throw new RuntimeException("该库位已被合并,刷新后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 查询钢卷物料表列表
|
* 查询钢卷物料表列表
|
||||||
*/
|
*/
|
||||||
@@ -698,7 +745,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
}else {
|
}else {
|
||||||
add.setDataType(1); // 新增的钢卷默认为当前数据
|
add.setDataType(1); // 新增的钢卷默认为当前数据
|
||||||
}
|
}
|
||||||
|
// 实际库位校验:占用与拆分/层级规则
|
||||||
|
if (bo.getActualWarehouseId() != null) {
|
||||||
|
validateActualWarehouseForAssign(bo.getActualWarehouseId(), null);
|
||||||
|
}
|
||||||
validEntityBeforeSave(add);
|
validEntityBeforeSave(add);
|
||||||
|
// 在新增钢卷数据之前需要先看库区id是否被占用如果被占用则不能新增抛异常为实际库区已被占用 不能再当前库区修改或者新增
|
||||||
int rows = baseMapper.insert(add);
|
int rows = baseMapper.insert(add);
|
||||||
if (rows <= 0) {
|
if (rows <= 0) {
|
||||||
throw new RuntimeException("新增钢卷失败");
|
throw new RuntimeException("新增钢卷失败");
|
||||||
@@ -842,6 +894,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
throw new RuntimeException("钢卷不存在");
|
throw new RuntimeException("钢卷不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 若修改实际库位,先进行校验
|
||||||
|
if (bo.getActualWarehouseId() != null) {
|
||||||
|
// 若与原库位不同,常规占用校验;若相同,仅校验拆分/层级
|
||||||
|
Long ignoreOccupiedId = Objects.equals(bo.getActualWarehouseId(), oldCoil.getActualWarehouseId())
|
||||||
|
? bo.getActualWarehouseId() : null;
|
||||||
|
validateActualWarehouseForAssign(bo.getActualWarehouseId(), ignoreOccupiedId);
|
||||||
|
}
|
||||||
|
|
||||||
// 直接更新钢卷属性
|
// 直接更新钢卷属性
|
||||||
WmsMaterialCoil updateCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class);
|
WmsMaterialCoil updateCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class);
|
||||||
validEntityBeforeSave(updateCoil);
|
validEntityBeforeSave(updateCoil);
|
||||||
@@ -889,6 +949,13 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
throw new RuntimeException("原钢卷不存在");
|
throw new RuntimeException("原钢卷不存在");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 若修改实际库位,先进行校验
|
||||||
|
if (bo.getActualWarehouseId() != null) {
|
||||||
|
Long ignoreOccupiedId = Objects.equals(bo.getActualWarehouseId(), oldCoil.getActualWarehouseId())
|
||||||
|
? bo.getActualWarehouseId() : null;
|
||||||
|
validateActualWarehouseForAssign(bo.getActualWarehouseId(), ignoreOccupiedId);
|
||||||
|
}
|
||||||
|
|
||||||
// 1. 将原钢卷标记为历史数据(dataType = 0)
|
// 1. 将原钢卷标记为历史数据(dataType = 0)
|
||||||
LambdaUpdateWrapper<WmsMaterialCoil> updateWrapper = new LambdaUpdateWrapper<>();
|
LambdaUpdateWrapper<WmsMaterialCoil> updateWrapper = new LambdaUpdateWrapper<>();
|
||||||
updateWrapper.eq(WmsMaterialCoil::getCoilId, oldCoil.getCoilId())
|
updateWrapper.eq(WmsMaterialCoil::getCoilId, oldCoil.getCoilId())
|
||||||
@@ -1102,6 +1169,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
|
|
||||||
// 3. 为每个分卷后的子钢卷生成独立的二维码并插入数据库
|
// 3. 为每个分卷后的子钢卷生成独立的二维码并插入数据库
|
||||||
for (WmsMaterialCoilBo newCoilBo : bo.getNewCoils()) {
|
for (WmsMaterialCoilBo newCoilBo : bo.getNewCoils()) {
|
||||||
|
// 校验每个子卷的实际库位
|
||||||
|
if (newCoilBo.getActualWarehouseId() != null) {
|
||||||
|
Long ignoreOccupiedId = (oldCoil != null && Objects.equals(newCoilBo.getActualWarehouseId(), oldCoil.getActualWarehouseId()))
|
||||||
|
? newCoilBo.getActualWarehouseId() : null;
|
||||||
|
validateActualWarehouseForAssign(newCoilBo.getActualWarehouseId(), ignoreOccupiedId);
|
||||||
|
}
|
||||||
WmsMaterialCoil newCoil = BeanUtil.toBean(newCoilBo, WmsMaterialCoil.class);
|
WmsMaterialCoil newCoil = BeanUtil.toBean(newCoilBo, WmsMaterialCoil.class);
|
||||||
newCoil.setCoilId(null);
|
newCoil.setCoilId(null);
|
||||||
newCoil.setDataType(1);
|
newCoil.setDataType(1);
|
||||||
@@ -1180,6 +1253,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService {
|
|||||||
Long mergedQrcodeId = generateQrcodeForMerge(bo, bo.getNewCoils());
|
Long mergedQrcodeId = generateQrcodeForMerge(bo, bo.getNewCoils());
|
||||||
|
|
||||||
// 3. 插入合卷后的新钢卷
|
// 3. 插入合卷后的新钢卷
|
||||||
|
// 合卷结果若指定了实际库位,先进行校验
|
||||||
|
if (bo.getActualWarehouseId() != null) {
|
||||||
|
validateActualWarehouseForAssign(bo.getActualWarehouseId(), null);
|
||||||
|
}
|
||||||
WmsMaterialCoil newCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class);
|
WmsMaterialCoil newCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class);
|
||||||
newCoil.setCoilId(null);
|
newCoil.setCoilId(null);
|
||||||
newCoil.setDataType(1);
|
newCoil.setDataType(1);
|
||||||
|
|||||||
Reference in New Issue
Block a user