Commit bbb338b6aa4ef3f1399f5cec17546c1e2248f100

Authored by YunaiV
1 parent 63239ca1

✨ feat(mes): 增强库存事务处理与编码生成

- 优化 selectByCompositeKey 方法,改进批次 ID 的处理逻辑
- 新增多个错误码以增强错误处理
- 更新样品编号和入库单编号生成逻辑,使用自动编码 API
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/materialstock/MesWmMaterialStockMapper.java
... ... @@ -74,12 +74,18 @@ public interface MesWmMaterialStockMapper extends BaseMapperX<MesWmMaterialStock
74 74  
75 75 default MesWmMaterialStockDO selectByCompositeKey(Long itemId, Long warehouseId, Long locationId,
76 76 Long areaId, Long batchId) {
77   - return selectOne(new LambdaQueryWrapperX<MesWmMaterialStockDO>()
  77 + LambdaQueryWrapperX<MesWmMaterialStockDO> wrapper = new LambdaQueryWrapperX<MesWmMaterialStockDO>()
78 78 .eqIfPresent(MesWmMaterialStockDO::getItemId, itemId)
79 79 .eqIfPresent(MesWmMaterialStockDO::getWarehouseId, warehouseId)
80 80 .eqIfPresent(MesWmMaterialStockDO::getLocationId, locationId)
81   - .eqIfPresent(MesWmMaterialStockDO::getAreaId, areaId)
82   - .eqIfPresent(MesWmMaterialStockDO::getBatchId, batchId));
  81 + .eqIfPresent(MesWmMaterialStockDO::getAreaId, areaId);
  82 + // batchId=null 时精确匹配 is null,避免 eqIfPresent 跳过条件导致匹配到其他批次
  83 + if (batchId != null) {
  84 + wrapper.eq(MesWmMaterialStockDO::getBatchId, batchId);
  85 + } else {
  86 + wrapper.isNull(MesWmMaterialStockDO::getBatchId);
  87 + }
  88 + return selectOne(wrapper);
83 89 }
84 90  
85 91 default List<MesWmMaterialStockDO> selectList(MesWmMaterialStockListReqVO reqVO) {
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -393,6 +393,8 @@ public interface ErrorCodeConstants {
393 393 ErrorCode WM_MATERIAL_STOCK_AREA_ITEM_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_008, "库位({})不允许物料混放,请选择其他库位");
394 394 ErrorCode WM_MATERIAL_STOCK_AREA_BATCH_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_009, "库位({})不允许批次混放,请选择其他库位");
395 395 ErrorCode WM_TRANSACTION_RELATED_NOT_EXISTS = new ErrorCode(1_040_703_010, "关联的库存事务不存在");
  396 + ErrorCode WM_TRANSACTION_LIST_EMPTY = new ErrorCode(1_040_703_011, "库存事务列表不能为空");
  397 + ErrorCode WM_TRANSACTION_BATCH_NOT_EXISTS = new ErrorCode(1_040_703_012, "批次记录不存在");
396 398  
397 399 // ========== MES 仓库管理-到货通知单(1-040-704-000) ==========
398 400 ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在");
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java
... ... @@ -48,8 +48,9 @@ public enum MesMdAutoCodeRuleCodeEnum {
48 48 PRO_ROUTE_CODE("PRO_ROUTE_CODE", "工艺路线编码"),
49 49 PRO_FEEDBACK_CODE("PRO_FEEDBACK_CODE", "生产报工单编码"),
50 50 PRO_WORK_ORDER_CODE("PRO_WORK_ORDER_CODE", "生产工单编码"),
51   - PRO_CARD_CODE("PRO_CARD_CODE", "流转卡编码"),
52   - QC_DEFECT_CODE("QC_DEFECT_CODE", "缺陷类型编码");
  51 + QC_DEFECT_CODE("QC_DEFECT_CODE", "缺陷类型编码"),
  52 + QC_INDICATOR_RESULT_CODE("QC_INDICATOR_RESULT_CODE", "样品检验结果编码"),
  53 + WM_OUTSOURCE_RECEIPT_CODE("WM_OUTSOURCE_RECEIPT_CODE", "外协入库单编码");
53 54  
54 55 /**
55 56 * 规则代码
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java
1 1 package cn.iocoder.yudao.module.mes.service.wm.transaction;
2 2  
  3 +import cn.hutool.core.collection.CollUtil;
3 4 import cn.hutool.core.lang.Assert;
4 5 import cn.hutool.core.util.ObjUtil;
5 6 import cn.hutool.core.util.StrUtil;
... ... @@ -58,7 +59,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
58 59 public Long createTransaction(MesWmTransactionSaveReqDTO reqDTO) {
59 60 // 1.1 校验事务类型
60 61 MesWmTransactionTypeEnum typeEnum = MesWmTransactionTypeEnum.valueOf(reqDTO.getType());
61   - Assert.notNull(typeEnum, "事务类型({}) 不存在", reqDTO.getType());
  62 + if (typeEnum == null) {
  63 + throw exception(WM_TRANSACTION_TYPE_NOT_EXISTS);
  64 + }
62 65 // 1.2 校验 quantity 正负号与事务方向一致(入库必须正数,出库必须负数)
63 66 boolean inbound = typeEnum.isInbound();
64 67 checkQuantity(reqDTO, inbound);
... ... @@ -96,6 +99,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
96 99 @Override
97 100 @Transactional(rollbackFor = Exception.class)
98 101 public void createTransactionList(List<MesWmTransactionSaveReqDTO> reqDTOs) {
  102 + if (CollUtil.isEmpty(reqDTOs)) {
  103 + throw exception(WM_TRANSACTION_LIST_EMPTY);
  104 + }
99 105 reqDTOs.forEach(this::createTransaction);
100 106 }
101 107  
... ... @@ -124,19 +130,21 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
124 130 // 1. batchId / batchCode 互补
125 131 if (reqDTO.getBatchId() != null && StrUtil.isEmpty(reqDTO.getBatchCode())) {
126 132 MesWmBatchDO batch = batchService.getBatch(reqDTO.getBatchId());
127   - if (batch != null) {
128   - reqDTO.setBatchCode(batch.getCode());
  133 + if (batch == null) {
  134 + throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
129 135 }
  136 + reqDTO.setBatchCode(batch.getCode());
130 137 } else if (StrUtil.isNotEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
131 138 MesWmBatchDO batch = batchService.getBatchByCode(reqDTO.getBatchCode());
132   - if (batch != null) {
133   - reqDTO.setBatchId(batch.getId());
  139 + if (batch == null) {
  140 + throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
134 141 }
  142 + reqDTO.setBatchId(batch.getId());
135 143 }
136 144 // 2. 入库时:启用批次管理的物料,必须传递批次号
137 145 if (inbound) {
138   - MesMdItemDO item = itemService.getItem(reqDTO.getItemId());
139   - if (item != null && Boolean.TRUE.equals(item.getBatchFlag())) {
  146 + MesMdItemDO item = itemService.validateItemExists(reqDTO.getItemId());
  147 + if (Boolean.TRUE.equals(item.getBatchFlag())) {
140 148 if (StrUtil.isEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
141 149 throw exception(WM_TRANSACTION_BATCH_REQUIRED);
142 150 }
... ...