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,12 +74,18 @@ public interface MesWmMaterialStockMapper extends BaseMapperX<MesWmMaterialStock
74 74
75 default MesWmMaterialStockDO selectByCompositeKey(Long itemId, Long warehouseId, Long locationId, 75 default MesWmMaterialStockDO selectByCompositeKey(Long itemId, Long warehouseId, Long locationId,
76 Long areaId, Long batchId) { 76 Long areaId, Long batchId) {
77 - return selectOne(new LambdaQueryWrapperX<MesWmMaterialStockDO>() 77 + LambdaQueryWrapperX<MesWmMaterialStockDO> wrapper = new LambdaQueryWrapperX<MesWmMaterialStockDO>()
78 .eqIfPresent(MesWmMaterialStockDO::getItemId, itemId) 78 .eqIfPresent(MesWmMaterialStockDO::getItemId, itemId)
79 .eqIfPresent(MesWmMaterialStockDO::getWarehouseId, warehouseId) 79 .eqIfPresent(MesWmMaterialStockDO::getWarehouseId, warehouseId)
80 .eqIfPresent(MesWmMaterialStockDO::getLocationId, locationId) 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 default List<MesWmMaterialStockDO> selectList(MesWmMaterialStockListReqVO reqVO) { 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,6 +393,8 @@ public interface ErrorCodeConstants {
393 ErrorCode WM_MATERIAL_STOCK_AREA_ITEM_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_008, "库位({})不允许物料混放,请选择其他库位"); 393 ErrorCode WM_MATERIAL_STOCK_AREA_ITEM_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_008, "库位({})不允许物料混放,请选择其他库位");
394 ErrorCode WM_MATERIAL_STOCK_AREA_BATCH_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_009, "库位({})不允许批次混放,请选择其他库位"); 394 ErrorCode WM_MATERIAL_STOCK_AREA_BATCH_MIXING_NOT_ALLOWED = new ErrorCode(1_040_703_009, "库位({})不允许批次混放,请选择其他库位");
395 ErrorCode WM_TRANSACTION_RELATED_NOT_EXISTS = new ErrorCode(1_040_703_010, "关联的库存事务不存在"); 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 // ========== MES 仓库管理-到货通知单(1-040-704-000) ========== 399 // ========== MES 仓库管理-到货通知单(1-040-704-000) ==========
398 ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在"); 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,8 +48,9 @@ public enum MesMdAutoCodeRuleCodeEnum {
48 PRO_ROUTE_CODE("PRO_ROUTE_CODE", "工艺路线编码"), 48 PRO_ROUTE_CODE("PRO_ROUTE_CODE", "工艺路线编码"),
49 PRO_FEEDBACK_CODE("PRO_FEEDBACK_CODE", "生产报工单编码"), 49 PRO_FEEDBACK_CODE("PRO_FEEDBACK_CODE", "生产报工单编码"),
50 PRO_WORK_ORDER_CODE("PRO_WORK_ORDER_CODE", "生产工单编码"), 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 package cn.iocoder.yudao.module.mes.service.wm.transaction; 1 package cn.iocoder.yudao.module.mes.service.wm.transaction;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.hutool.core.lang.Assert; 4 import cn.hutool.core.lang.Assert;
4 import cn.hutool.core.util.ObjUtil; 5 import cn.hutool.core.util.ObjUtil;
5 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
@@ -58,7 +59,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService { @@ -58,7 +59,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
58 public Long createTransaction(MesWmTransactionSaveReqDTO reqDTO) { 59 public Long createTransaction(MesWmTransactionSaveReqDTO reqDTO) {
59 // 1.1 校验事务类型 60 // 1.1 校验事务类型
60 MesWmTransactionTypeEnum typeEnum = MesWmTransactionTypeEnum.valueOf(reqDTO.getType()); 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 // 1.2 校验 quantity 正负号与事务方向一致(入库必须正数,出库必须负数) 65 // 1.2 校验 quantity 正负号与事务方向一致(入库必须正数,出库必须负数)
63 boolean inbound = typeEnum.isInbound(); 66 boolean inbound = typeEnum.isInbound();
64 checkQuantity(reqDTO, inbound); 67 checkQuantity(reqDTO, inbound);
@@ -96,6 +99,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService { @@ -96,6 +99,9 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
96 @Override 99 @Override
97 @Transactional(rollbackFor = Exception.class) 100 @Transactional(rollbackFor = Exception.class)
98 public void createTransactionList(List<MesWmTransactionSaveReqDTO> reqDTOs) { 101 public void createTransactionList(List<MesWmTransactionSaveReqDTO> reqDTOs) {
  102 + if (CollUtil.isEmpty(reqDTOs)) {
  103 + throw exception(WM_TRANSACTION_LIST_EMPTY);
  104 + }
99 reqDTOs.forEach(this::createTransaction); 105 reqDTOs.forEach(this::createTransaction);
100 } 106 }
101 107
@@ -124,19 +130,21 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService { @@ -124,19 +130,21 @@ public class MesWmTransactionServiceImpl implements MesWmTransactionService {
124 // 1. batchId / batchCode 互补 130 // 1. batchId / batchCode 互补
125 if (reqDTO.getBatchId() != null && StrUtil.isEmpty(reqDTO.getBatchCode())) { 131 if (reqDTO.getBatchId() != null && StrUtil.isEmpty(reqDTO.getBatchCode())) {
126 MesWmBatchDO batch = batchService.getBatch(reqDTO.getBatchId()); 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 } else if (StrUtil.isNotEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) { 137 } else if (StrUtil.isNotEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
131 MesWmBatchDO batch = batchService.getBatchByCode(reqDTO.getBatchCode()); 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 // 2. 入库时:启用批次管理的物料,必须传递批次号 144 // 2. 入库时:启用批次管理的物料,必须传递批次号
137 if (inbound) { 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 if (StrUtil.isEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) { 148 if (StrUtil.isEmpty(reqDTO.getBatchCode()) && reqDTO.getBatchId() == null) {
141 throw exception(WM_TRANSACTION_BATCH_REQUIRED); 149 throw exception(WM_TRANSACTION_BATCH_REQUIRED);
142 } 150 }