Преглед изворни кода

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

- 优化 selectByCompositeKey 方法,改进批次 ID 的处理逻辑
- 新增多个错误码以增强错误处理
- 更新样品编号和入库单编号生成逻辑,使用自动编码 API
YunaiV пре 5 месеци
родитељ
комит
bbb338b6aa

+ 9 - 3
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
 
     default MesWmMaterialStockDO selectByCompositeKey(Long itemId, Long warehouseId, Long locationId,
                                                        Long areaId, Long batchId) {
-        return selectOne(new LambdaQueryWrapperX<MesWmMaterialStockDO>()
+        LambdaQueryWrapperX<MesWmMaterialStockDO> wrapper = new LambdaQueryWrapperX<MesWmMaterialStockDO>()
                 .eqIfPresent(MesWmMaterialStockDO::getItemId, itemId)
                 .eqIfPresent(MesWmMaterialStockDO::getWarehouseId, warehouseId)
                 .eqIfPresent(MesWmMaterialStockDO::getLocationId, locationId)
-                .eqIfPresent(MesWmMaterialStockDO::getAreaId, areaId)
-                .eqIfPresent(MesWmMaterialStockDO::getBatchId, batchId));
+                .eqIfPresent(MesWmMaterialStockDO::getAreaId, areaId);
+        // batchId=null 时精确匹配 is null,避免 eqIfPresent 跳过条件导致匹配到其他批次
+        if (batchId != null) {
+            wrapper.eq(MesWmMaterialStockDO::getBatchId, batchId);
+        } else {
+            wrapper.isNull(MesWmMaterialStockDO::getBatchId);
+        }
+        return selectOne(wrapper);
     }
 
     default List<MesWmMaterialStockDO> selectList(MesWmMaterialStockListReqVO reqVO) {

+ 2 - 0
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java

@@ -393,6 +393,8 @@ public interface ErrorCodeConstants {
     ErrorCode WM_MATERIAL_STOCK_AREA_ITEM_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_008, "库位({})不允许物料混放,请选择其他库位");
     ErrorCode WM_MATERIAL_STOCK_AREA_BATCH_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_009, "库位({})不允许批次混放,请选择其他库位");
     ErrorCode WM_TRANSACTION_RELATED_NOT_EXISTS = new ErrorCode(1_040_703_010, "关联的库存事务不存在");
+    ErrorCode WM_TRANSACTION_LIST_EMPTY = new ErrorCode(1_040_703_011, "库存事务列表不能为空");
+    ErrorCode WM_TRANSACTION_BATCH_NOT_EXISTS = new ErrorCode(1_040_703_012, "批次记录不存在");
 
     // ========== MES 仓库管理-到货通知单(1-040-704-000) ==========
     ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在");

+ 3 - 2
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java

@@ -48,8 +48,9 @@ public enum MesMdAutoCodeRuleCodeEnum {
     PRO_ROUTE_CODE("PRO_ROUTE_CODE", "工艺路线编码"),
     PRO_FEEDBACK_CODE("PRO_FEEDBACK_CODE", "生产报工单编码"),
     PRO_WORK_ORDER_CODE("PRO_WORK_ORDER_CODE", "生产工单编码"),
-    PRO_CARD_CODE("PRO_CARD_CODE", "流转卡编码"),
-    QC_DEFECT_CODE("QC_DEFECT_CODE", "缺陷类型编码");
+    QC_DEFECT_CODE("QC_DEFECT_CODE", "缺陷类型编码"),
+    QC_INDICATOR_RESULT_CODE("QC_INDICATOR_RESULT_CODE", "样品检验结果编码"),
+    WM_OUTSOURCE_RECEIPT_CODE("WM_OUTSOURCE_RECEIPT_CODE", "外协入库单编码");
 
     /**
      * 规则代码

+ 15 - 7
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/transaction/MesWmTransactionServiceImpl.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.module.mes.service.wm.transaction;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.Assert;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.StrUtil;
@@ -58,7 +59,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
     public Long createTransaction(MesWmTransactionSaveReqDTO reqDTO) {
         // 1.1 校验事务类型
         MesWmTransactionTypeEnum typeEnum = MesWmTransactionTypeEnum.valueOf(reqDTO.getType());
-        Assert.notNull(typeEnum, "事务类型({}) 不存在", reqDTO.getType());
+        if (typeEnum == null) {
+            throw exception(WM_TRANSACTION_TYPE_NOT_EXISTS);
+        }
         // 1.2 校验 quantity 正负号与事务方向一致(入库必须正数,出库必须负数)
         boolean inbound = typeEnum.isInbound();
         checkQuantity(reqDTO, inbound);
@@ -96,6 +99,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void createTransactionList(List<MesWmTransactionSaveReqDTO> reqDTOs) {
+        if (CollUtil.isEmpty(reqDTOs)) {
+            throw exception(WM_TRANSACTION_LIST_EMPTY);
+        }
         reqDTOs.forEach(this::createTransaction);
     }
 
@@ -124,19 +130,21 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
         // 1. batchId / batchCode 互补
         if (reqDTO.getBatchId() != null && StrUtil.isEmpty(reqDTO.getBatchCode())) {
             MesWmBatchDO batch = batchService.getBatch(reqDTO.getBatchId());
-            if (batch != null) {
-                reqDTO.setBatchCode(batch.getCode());
+            if (batch == null) {
+                throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
             }
+            reqDTO.setBatchCode(batch.getCode());
         } else if (StrUtil.isNotEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
             MesWmBatchDO batch = batchService.getBatchByCode(reqDTO.getBatchCode());
-            if (batch != null) {
-                reqDTO.setBatchId(batch.getId());
+            if (batch == null) {
+                throw exception(WM_TRANSACTION_BATCH_NOT_EXISTS);
             }
+            reqDTO.setBatchId(batch.getId());
         }
         // 2. 入库时:启用批次管理的物料,必须传递批次号
         if (inbound) {
-            MesMdItemDO item = itemService.getItem(reqDTO.getItemId());
-            if (item != null && Boolean.TRUE.equals(item.getBatchFlag())) {
+            MesMdItemDO item = itemService.validateItemExists(reqDTO.getItemId());
+            if (Boolean.TRUE.equals(item.getBatchFlag())) {
                 if (StrUtil.isEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
                     throw exception(WM_TRANSACTION_BATCH_REQUIRED);
                 }