diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index 35374dc8..62295b60 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -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 boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType()); boolean hasAnyItemFilter = StringUtils.isNotBlank(bo.getItemMaterial()) @@ -624,6 +629,48 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { // 一级库位或其他类型:返回自身ID 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 { add.setDataType(1); // 新增的钢卷默认为当前数据 } + // 实际库位校验:占用与拆分/层级规则 + if (bo.getActualWarehouseId() != null) { + validateActualWarehouseForAssign(bo.getActualWarehouseId(), null); + } validEntityBeforeSave(add); + // 在新增钢卷数据之前需要先看库区id是否被占用如果被占用则不能新增抛异常为实际库区已被占用 不能再当前库区修改或者新增 int rows = baseMapper.insert(add); if (rows <= 0) { throw new RuntimeException("新增钢卷失败"); @@ -842,6 +894,14 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { 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); validEntityBeforeSave(updateCoil); @@ -889,6 +949,13 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { 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) LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(WmsMaterialCoil::getCoilId, oldCoil.getCoilId()) @@ -1102,6 +1169,12 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { // 3. 为每个分卷后的子钢卷生成独立的二维码并插入数据库 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); newCoil.setCoilId(null); newCoil.setDataType(1); @@ -1180,6 +1253,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { Long mergedQrcodeId = generateQrcodeForMerge(bo, bo.getNewCoils()); // 3. 插入合卷后的新钢卷 + // 合卷结果若指定了实际库位,先进行校验 + if (bo.getActualWarehouseId() != null) { + validateActualWarehouseForAssign(bo.getActualWarehouseId(), null); + } WmsMaterialCoil newCoil = BeanUtil.toBean(bo, WmsMaterialCoil.class); newCoil.setCoilId(null); newCoil.setDataType(1);