Commit 627bbba382db3c4dd53bc4475d16212eff38f27a
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
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
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
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, | ... | ... |