Commit 627bbba382db3c4dd53bc4475d16212eff38f27a

Authored by YunaiV
1 parent cc29c141

✨ feat(mes): 新增库存记录和批次编码字段,优化退料单功能

在退料单相关的多个类中新增库存记录 ID 和批次编码字段,以支持更精确的库存管理和数据校验。同时,更新了相关的表单和服务逻辑,确保新字段的正确使用和验证。
Showing 15 changed files with 85 additions and 7 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/MesWmReturnIssueLineController.java
... ... @@ -41,7 +41,6 @@ public class MesWmReturnIssueLineController {
41 41  
42 42 @Resource
43 43 private MesMdItemService itemService;
44   -
45 44 @Resource
46 45 private MesMdUnitMeasureService unitMeasureService;
47 46  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineRespVO.java
... ... @@ -31,12 +31,18 @@ public class MesWmReturnIssueLineRespVO {
31 31 @Schema(description = "计量单位名称", example = "千克")
32 32 private String unitMeasureName;
33 33  
  34 + @Schema(description = "库存记录 ID", example = "1")
  35 + private Long materialStockId;
  36 +
34 37 @Schema(description = "退料数量", example = "100.00")
35 38 private BigDecimal quantity;
36 39  
37 40 @Schema(description = "批次 ID", example = "1")
38 41 private Long batchId;
39 42  
  43 + @Schema(description = "批次编码", example = "BAT202601001")
  44 + private String batchCode;
  45 +
40 46 @Schema(description = "是否需要质检", example = "false")
41 47 private Boolean rqcCheckFlag;
42 48  
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnissue/vo/line/MesWmReturnIssueLineSaveReqVO.java
... ... @@ -27,9 +27,15 @@ public class MesWmReturnIssueLineSaveReqVO {
27 27 @DecimalMin(value = "0", inclusive = false, message = "退料数量必须大于 0")
28 28 private BigDecimal quantity;
29 29  
  30 + @Schema(description = "库存记录 ID", example = "1")
  31 + private Long materialStockId;
  32 +
30 33 @Schema(description = "批次 ID", example = "1")
31 34 private Long batchId;
32 35  
  36 + @Schema(description = "批次编码", example = "BCH20260330001")
  37 + private String batchCode;
  38 +
33 39 @Schema(description = "是否需要质检", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
34 40 @NotNull(message = "是否需要质检不能为空")
35 41 private Boolean rqcCheckFlag;
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueDO.java
... ... @@ -43,7 +43,6 @@ public class MesWmReturnIssueDO extends BaseDO {
43 43 * 关联 {@link MesProWorkOrderDO#getId()}
44 44 */
45 45 private Long workOrderId;
46   - // TODO @芋艿:可能不需要这个字段。界面上没有;
47 46 /**
48 47 * 工作站 ID
49 48 *
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnissue/MesWmReturnIssueLineDO.java
... ... @@ -2,6 +2,9 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue;
2 2  
3 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
  5 +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcDO;
  6 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.batch.MesWmBatchDO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.materialstock.MesWmMaterialStockDO;
5 8 import com.baomidou.mybatisplus.annotation.KeySequence;
6 9 import com.baomidou.mybatisplus.annotation.TableId;
7 10 import com.baomidou.mybatisplus.annotation.TableName;
... ... @@ -35,6 +38,8 @@ public class MesWmReturnIssueLineDO extends BaseDO {
35 38 private Long issueId;
36 39 /**
37 40 * 库存记录 ID
  41 + *
  42 + * 关联 {@link MesWmMaterialStockDO#getId()}
38 43 */
39 44 private Long materialStockId;
40 45 /**
... ... @@ -49,10 +54,20 @@ public class MesWmReturnIssueLineDO extends BaseDO {
49 54 private BigDecimal quantity;
50 55 /**
51 56 * 批次 ID
  57 + *
  58 + * 关联 {@link MesWmBatchDO#getId()}
52 59 */
53 60 private Long batchId;
54 61 /**
  62 + * 批次编码
  63 + *
  64 + * 关联 {@link MesWmBatchDO#getCode()}
  65 + */
  66 + private String batchCode;
  67 + /**
55 68 * 退货检验单 ID
  69 + *
  70 + * 关联 {@link MesQcRqcDO#getId()}
56 71 */
57 72 private Long rqcId;
58 73 /**
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueDetailMapper.java
... ... @@ -24,4 +24,8 @@ public interface MesWmReturnIssueDetailMapper extends BaseMapperX<MesWmReturnIss
24 24 delete(MesWmReturnIssueDetailDO::getIssueId, issueId);
25 25 }
26 26  
  27 + default void deleteByLineId(Long lineId) {
  28 + delete(MesWmReturnIssueDetailDO::getLineId, lineId);
  29 + }
  30 +
27 31 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/returnissue/MesWmReturnIssueMapper.java
... ... @@ -23,4 +23,8 @@ public interface MesWmReturnIssueMapper extends BaseMapperX<MesWmReturnIssueDO>
23 23 .orderByDesc(MesWmReturnIssueDO::getId));
24 24 }
25 25  
  26 + default MesWmReturnIssueDO selectByCode(String code) {
  27 + return selectOne(MesWmReturnIssueDO::getCode, code);
  28 + }
  29 +
26 30 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
... ... @@ -468,6 +468,7 @@ public interface ErrorCodeConstants {
468 468 ErrorCode WM_RETURN_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_710_200, "生产退料单明细不存在");
469 469 ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_INVALID = new ErrorCode(1_040_710_201, "退料明细数量必须大于0");
470 470 ErrorCode WM_RETURN_ISSUE_DETAIL_QUANTITY_EXCEED = new ErrorCode(1_040_710_202, "退料明细总数量不能超过退料单行数量");
  471 + ErrorCode WM_RETURN_ISSUE_CODE_DUPLICATE = new ErrorCode(1_040_710_203, "退料单编码已存在");
471 472  
472 473 // ========== MES 仓库管理-供应商退货单(1-040-711-000) ==========
473 474 ErrorCode WM_RETURN_VENDOR_NOT_EXISTS = new ErrorCode(1_040_711_000, "供应商退货单不存在");
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java
... ... @@ -20,6 +20,7 @@ public enum MesMdAutoCodeRuleCodeEnum {
20 20 WM_ARRIVAL_NOTICE_CODE("WM_ARRIVAL_NOTICE_CODE", "到货通知单编码"),
21 21 WM_ITEM_RECEIPT_CODE("WM_ITEM_RECEIPT_CODE", "采购入库单编码"),
22 22 WM_RETURN_VENDOR_CODE("WM_RETURN_VENDOR_CODE", "采购退货单编码"),
  23 + WM_RETURN_ISSUE_CODE("WM_RETURN_ISSUE_CODE", "生产退料单编码"),
23 24 WM_SN_CODE("WM_SN_CODE", "SN 码"),
24 25 WM_PACKAGE_CODE("WM_PACKAGE_CODE", "装箱单编码"),
25 26 WM_BATCH_CODE("WM_BATCH_CODE", "批次编码"),
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailService.java
... ... @@ -64,4 +64,11 @@ public interface MesWmReturnIssueDetailService {
64 64 */
65 65 void deleteReturnIssueDetailByIssueId(Long issueId);
66 66  
  67 + /**
  68 + * 根据行 ID 删除明细
  69 + *
  70 + * @param lineId 行 ID
  71 + */
  72 + void deleteReturnIssueDetailByLineId(Long lineId);
  73 +
67 74 }
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueDetailServiceImpl.java
... ... @@ -87,6 +87,11 @@ public class MesWmReturnIssueDetailServiceImpl implements MesWmReturnIssueDetail
87 87 issueDetailMapper.deleteByIssueId(issueId);
88 88 }
89 89  
  90 + @Override
  91 + public void deleteReturnIssueDetailByLineId(Long lineId) {
  92 + issueDetailMapper.deleteByLineId(lineId);
  93 + }
  94 +
90 95 private void validateReturnIssueDetailExists(Long id) {
91 96 if (issueDetailMapper.selectById(id) == null) {
92 97 throw exception(WM_RETURN_ISSUE_DETAIL_NOT_EXISTS);
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
... ... @@ -40,6 +40,9 @@ public class MesWmReturnIssueLineServiceImpl implements MesWmReturnIssueLineServ
40 40 private MesWmReturnIssueService issueService;
41 41 @Resource
42 42 private MesMdItemService itemService;
  43 + @Resource
  44 + @Lazy
  45 + private MesWmReturnIssueDetailService issueDetailService;
43 46  
44 47 @Override
45 48 public Long createReturnIssueLine(MesWmReturnIssueLineSaveReqVO createReqVO) {
... ... @@ -69,8 +72,12 @@ public class MesWmReturnIssueLineServiceImpl implements MesWmReturnIssueLineServ
69 72 @Override
70 73 public void deleteReturnIssueLine(Long id) {
71 74 // 校验存在
72   - validateReturnIssueLineExists(id);
73   - // 删除
  75 + MesWmReturnIssueLineDO line = validateReturnIssueLineExists(id);
  76 + // 校验主单为草稿状态才允许删除行
  77 + issueService.validateReturnIssueExistsAndPrepare(line.getIssueId());
  78 + // 级联删除该行的明细
  79 + issueDetailService.deleteReturnIssueDetailByLineId(id);
  80 + // 删除行
74 81 issueLineMapper.deleteById(id);
75 82 }
76 83  
... ... @@ -107,8 +114,8 @@ public class MesWmReturnIssueLineServiceImpl implements MesWmReturnIssueLineServ
107 114 * 校验保存时的关联数据
108 115 */
109 116 private MesWmReturnIssueDO validateReturnIssueLineSaveData(MesWmReturnIssueLineSaveReqVO reqVO) {
110   - // 校验父数据存在
111   - MesWmReturnIssueDO issue = issueService.validateReturnIssueExists(reqVO.getIssueId());
  117 + // 校验父数据存在 + 草稿状态
  118 + MesWmReturnIssueDO issue = issueService.validateReturnIssueExistsAndPrepare(reqVO.getIssueId());
112 119 // 校验物料存在
113 120 itemService.validateItemExists(reqVO.getItemId());
114 121 return issue;
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueService.java
... ... @@ -58,6 +58,14 @@ public interface MesWmReturnIssueService {
58 58 MesWmReturnIssueDO validateReturnIssueExists(Long id);
59 59  
60 60 /**
  61 + * 校验生产退料单存在且为准备中状态
  62 + *
  63 + * @param id 编号
  64 + * @return 生产退料单
  65 + */
  66 + MesWmReturnIssueDO validateReturnIssueExistsAndPrepare(Long id);
  67 +
  68 + /**
61 69 * 提交生产退料单(草稿 → 待检验/待上架)
62 70 *
63 71 * @param id 编号
... ...
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
... ... @@ -254,7 +254,8 @@ public class MesWmReturnIssueServiceImpl implements MesWmReturnIssueService {
254 254 /**
255 255 * 校验生产退料单存在且为准备中状态
256 256 */
257   - private MesWmReturnIssueDO validateReturnIssueExistsAndPrepare(Long id) {
  257 + @Override
  258 + public MesWmReturnIssueDO validateReturnIssueExistsAndPrepare(Long id) {
258 259 MesWmReturnIssueDO issue = validateReturnIssueExists(id);
259 260 if (ObjUtil.notEqual(MesWmReturnIssueStatusEnum.PREPARE.getStatus(), issue.getStatus())) {
260 261 throw exception(WM_RETURN_ISSUE_NOT_PREPARE);
... ... @@ -269,9 +270,23 @@ public class MesWmReturnIssueServiceImpl implements MesWmReturnIssueService {
269 270 }
270 271  
271 272 /**
  273 + * 校验编码唯一性
  274 + */
  275 + private void validateCodeUnique(Long id, String code) {
  276 + MesWmReturnIssueDO issue = issueMapper.selectByCode(code);
  277 + if (issue == null) {
  278 + return;
  279 + }
  280 + if (ObjUtil.notEqual(id, issue.getId())) {
  281 + throw exception(WM_RETURN_ISSUE_CODE_DUPLICATE);
  282 + }
  283 + }
  284 +
  285 + /**
272 286 * 校验保存时的关联数据
273 287 */
274 288 private void validateReturnIssueSaveData(MesWmReturnIssueSaveReqVO reqVO) {
  289 + validateCodeUnique(reqVO.getId(), reqVO.getCode());
275 290 workOrderService.validateWorkOrderExists(reqVO.getWorkOrderId());
276 291 if (reqVO.getWorkstationId() != null) {
277 292 workstationService.validateWorkstationExists(reqVO.getWorkstationId());
... ...
yudao-module-mes/src/test/resources/sql/create_tables.sql
... ... @@ -414,6 +414,7 @@ CREATE TABLE IF NOT EXISTS "mes_wm_return_issue_line" (
414 414 "item_id" bigint NOT NULL,
415 415 "quantity" decimal(12,2) NOT NULL DEFAULT 0.00,
416 416 "batch_id" bigint DEFAULT NULL,
  417 + "batch_code" varchar(255) DEFAULT NULL,
417 418 "rqc_id" bigint DEFAULT NULL,
418 419 "rqc_check_flag" bit NOT NULL DEFAULT FALSE,
419 420 "quality_status" int DEFAULT NULL,
... ...