Commit 67193b0c3b4eb90bc13ba1804243ffbbe617e542
1 parent
6f4aa8fd
✨ feat(mes): 添加生产领料出库单相关功能与组件
新增生产领料出库单的相关数据模型、接口及前端组件,支持领料单的创建、编辑和完成操作。优化了数据校验逻辑,并添加了物料、库存和工单选择器,提升用户体验。 - 实现领料单的基本 CRUD 操作 - 增加物料和库存选择功能 - 优化前端表单布局与交互
Showing
6 changed files
with
88 additions
and
98 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java
| @@ -34,6 +34,9 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPOR | @@ -34,6 +34,9 @@ import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPOR | ||
| 34 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 34 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 35 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 35 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 36 | 36 | ||
| 37 | +// TODO @AI:方法的排序,参考别的模块; | ||
| 38 | +// TODO @AI:controller、service、包括其他的,都需要全。createProductitonIssue 这种;其它模块也是; | ||
| 39 | +// TODO @AI:需要新增 line、detail 的 controller;参考 /Users/yunai/Java/yudao-all-in-one/ruoyi-vue-pro/yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt | ||
| 37 | @Tag(name = "管理后台 - MES 领料出库单") | 40 | @Tag(name = "管理后台 - MES 领料出库单") |
| 38 | @RestController | 41 | @RestController |
| 39 | @RequestMapping("/mes/wm/production-issue") | 42 | @RequestMapping("/mes/wm/production-issue") |
| @@ -102,24 +105,6 @@ public class MesWmProductionIssueController { | @@ -102,24 +105,6 @@ public class MesWmProductionIssueController { | ||
| 102 | buildRespVOList(pageResult.getList())); | 105 | buildRespVOList(pageResult.getList())); |
| 103 | } | 106 | } |
| 104 | 107 | ||
| 105 | - @PutMapping("/approve") | ||
| 106 | - @Operation(summary = "审批领料出库单") | ||
| 107 | - @Parameter(name = "id", description = "编号", required = true) | ||
| 108 | - @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')") | ||
| 109 | - public CommonResult<Boolean> approveIssue(@RequestParam("id") Long id) { | ||
| 110 | - issueService.approveIssue(id); | ||
| 111 | - return success(true); | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - @PutMapping("/unapprove") | ||
| 115 | - @Operation(summary = "反审批领料出库单") | ||
| 116 | - @Parameter(name = "id", description = "编号", required = true) | ||
| 117 | - @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')") | ||
| 118 | - public CommonResult<Boolean> unapproveIssue(@RequestParam("id") Long id) { | ||
| 119 | - issueService.unapproveIssue(id); | ||
| 120 | - return success(true); | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | @PutMapping("/finish") | 108 | @PutMapping("/finish") |
| 124 | @Operation(summary = "完成领料出库单") | 109 | @Operation(summary = "完成领料出库单") |
| 125 | @Parameter(name = "id", description = "编号", required = true) | 110 | @Parameter(name = "id", description = "编号", required = true) |
| @@ -131,6 +116,7 @@ public class MesWmProductionIssueController { | @@ -131,6 +116,7 @@ public class MesWmProductionIssueController { | ||
| 131 | 116 | ||
| 132 | // ==================== 拼接 VO ==================== | 117 | // ==================== 拼接 VO ==================== |
| 133 | 118 | ||
| 119 | + // TODO @AI:这个方法的拼接,在优化下; | ||
| 134 | private List<MesWmProductionIssueRespVO> buildRespVOList(List<MesWmProductionIssueDO> list) { | 120 | private List<MesWmProductionIssueRespVO> buildRespVOList(List<MesWmProductionIssueDO> list) { |
| 135 | if (CollUtil.isEmpty(list)) { | 121 | if (CollUtil.isEmpty(list)) { |
| 136 | return Collections.emptyList(); | 122 | return Collections.emptyList(); |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java
| @@ -13,28 +13,25 @@ public class MesWmProductionIssueSaveReqVO { | @@ -13,28 +13,25 @@ public class MesWmProductionIssueSaveReqVO { | ||
| 13 | @Schema(description = "编号", example = "1024") | 13 | @Schema(description = "编号", example = "1024") |
| 14 | private Long id; | 14 | private Long id; |
| 15 | 15 | ||
| 16 | + // TODO @AI:必须传递 | ||
| 16 | @Schema(description = "领料单编号", example = "ISSUE20250226001") | 17 | @Schema(description = "领料单编号", example = "ISSUE20250226001") |
| 17 | private String code; | 18 | private String code; |
| 18 | 19 | ||
| 20 | + // TODO @AI:必须传递 | ||
| 19 | @Schema(description = "领料单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "生产领料") | 21 | @Schema(description = "领料单名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "生产领料") |
| 20 | private String name; | 22 | private String name; |
| 21 | 23 | ||
| 22 | - @Schema(description = "工作站ID", example = "1") | 24 | + // TODO @AI:必须传递 |
| 25 | + // TODO @AI:service 需要校验存在 | ||
| 26 | + @Schema(description = "工作站 ID", example = "1") | ||
| 23 | private Long workstationId; | 27 | private Long workstationId; |
| 24 | 28 | ||
| 25 | - @Schema(description = "生产工单ID", example = "1") | 29 | + @Schema(description = "生产工单 ID", example = "1") |
| 30 | + // TODO @AI:service 需要校验存在 | ||
| 26 | private Long workorderId; | 31 | private Long workorderId; |
| 27 | 32 | ||
| 28 | - @Schema(description = "生产任务ID", example = "1") | ||
| 29 | - private Long taskId; | ||
| 30 | - | ||
| 31 | - @Schema(description = "客户ID", example = "1") | ||
| 32 | - private Long clientId; | ||
| 33 | - | ||
| 34 | - @Schema(description = "领料日期") | ||
| 35 | - private LocalDateTime issueDate; | ||
| 36 | - | ||
| 37 | @Schema(description = "需求时间") | 33 | @Schema(description = "需求时间") |
| 34 | + // TODO @AI:必须传递 | ||
| 38 | private LocalDateTime requiredTime; | 35 | private LocalDateTime requiredTime; |
| 39 | 36 | ||
| 40 | @Schema(description = "备注", example = "备注") | 37 | @Schema(description = "备注", example = "备注") |
| @@ -52,6 +49,7 @@ public class MesWmProductionIssueSaveReqVO { | @@ -52,6 +49,7 @@ public class MesWmProductionIssueSaveReqVO { | ||
| 52 | @Schema(description = "预留字段4") | 49 | @Schema(description = "预留字段4") |
| 53 | private Integer attribute4; | 50 | private Integer attribute4; |
| 54 | 51 | ||
| 52 | + // TODO @AI:应该单独接口,传递这个;参考别的模块; | ||
| 55 | @Schema(description = "领料单行列表") | 53 | @Schema(description = "领料单行列表") |
| 56 | private List<MesWmProductionIssueLineSaveReqVO> lines; | 54 | private List<MesWmProductionIssueLineSaveReqVO> lines; |
| 57 | 55 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| @@ -357,4 +357,17 @@ public interface ErrorCodeConstants { | @@ -357,4 +357,17 @@ public interface ErrorCodeConstants { | ||
| 357 | ErrorCode WM_OUTSOURCE_ISSUE_QUANTITY_MISMATCH = new ErrorCode(1_040_707_002, "出库单行数量与明细数量不一致"); | 357 | ErrorCode WM_OUTSOURCE_ISSUE_QUANTITY_MISMATCH = new ErrorCode(1_040_707_002, "出库单行数量与明细数量不一致"); |
| 358 | ErrorCode WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_707_100, "外协出库单行不存在"); | 358 | ErrorCode WM_OUTSOURCE_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_707_100, "外协出库单行不存在"); |
| 359 | 359 | ||
| 360 | + // ========== MES 仓库管理-生产领料出库单(1-040-708-000) ========== | ||
| 361 | + ErrorCode WM_PRODUCTION_ISSUE_NOT_EXISTS = new ErrorCode(1_040_708_000, "生产领料出库单不存在"); | ||
| 362 | + ErrorCode WM_PRODUCTION_ISSUE_STATUS_INVALID = new ErrorCode(1_040_708_001, "生产领料出库单状态不正确,无法执行该操作"); | ||
| 363 | + // TODO @AI:不需要的错误码,需要处理下。 | ||
| 364 | + ErrorCode WM_PRODUCTION_ISSUE_WAREHOUSE_NOT_EXISTS = new ErrorCode(1_040_708_002, "仓库不存在"); | ||
| 365 | + ErrorCode WM_PRODUCTION_ISSUE_ITEM_NOT_EXISTS = new ErrorCode(1_040_708_003, "物料不存在"); | ||
| 366 | + ErrorCode WM_PRODUCTION_ISSUE_WORKORDER_NOT_EXISTS = new ErrorCode(1_040_708_004, "生产工单不存在"); | ||
| 367 | + ErrorCode WM_PRODUCTION_ISSUE_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_708_005, "工作站不存在"); | ||
| 368 | + ErrorCode WM_PRODUCTION_ISSUE_NO_LINE = new ErrorCode(1_040_708_006, "至少需要一条行项目"); | ||
| 369 | + ErrorCode WM_PRODUCTION_ISSUE_QUANTITY_MISMATCH = new ErrorCode(1_040_708_007, "领料单行数量与明细数量不一致"); | ||
| 370 | + ErrorCode WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_708_100, "生产领料出库单行不存在"); | ||
| 371 | + ErrorCode WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在"); | ||
| 372 | + | ||
| 360 | } | 373 | } |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductionIssueStatusEnum.java
| 1 | package cn.iocoder.yudao.module.mes.enums.wm; | 1 | package cn.iocoder.yudao.module.mes.enums.wm; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.core.ArrayValuable; | 3 | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| 4 | +import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; | ||
| 4 | import lombok.AllArgsConstructor; | 5 | import lombok.AllArgsConstructor; |
| 5 | import lombok.Getter; | 6 | import lombok.Getter; |
| 6 | 7 | ||
| 7 | import java.util.Arrays; | 8 | import java.util.Arrays; |
| 8 | 9 | ||
| 9 | -// TODO @AI:需要使用 status constants 去映射; | ||
| 10 | /** | 10 | /** |
| 11 | * MES 领料出库单状态枚举 | 11 | * MES 领料出库单状态枚举 |
| 12 | */ | 12 | */ |
| @@ -14,9 +14,8 @@ import java.util.Arrays; | @@ -14,9 +14,8 @@ import java.util.Arrays; | ||
| 14 | @AllArgsConstructor | 14 | @AllArgsConstructor |
| 15 | public enum MesWmProductionIssueStatusEnum implements ArrayValuable<Integer> { | 15 | public enum MesWmProductionIssueStatusEnum implements ArrayValuable<Integer> { |
| 16 | 16 | ||
| 17 | - PREPARE(10, "准备中"), | ||
| 18 | - APPROVED(20, "已审批"), | ||
| 19 | - FINISHED(30, "已完成"); | 17 | + PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), |
| 18 | + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"); | ||
| 20 | 19 | ||
| 21 | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductionIssueStatusEnum::getStatus).toArray(Integer[]::new); | 20 | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductionIssueStatusEnum::getStatus).toArray(Integer[]::new); |
| 22 | 21 |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java
| @@ -53,21 +53,7 @@ public interface MesWmProductionIssueService { | @@ -53,21 +53,7 @@ public interface MesWmProductionIssueService { | ||
| 53 | PageResult<MesWmProductionIssueDO> getIssuePage(MesWmProductionIssuePageReqVO pageReqVO); | 53 | PageResult<MesWmProductionIssueDO> getIssuePage(MesWmProductionIssuePageReqVO pageReqVO); |
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | - * 审批领料出库单(准备中 → 已审批,扣减库存) | ||
| 57 | - * | ||
| 58 | - * @param id 编号 | ||
| 59 | - */ | ||
| 60 | - void approveIssue(Long id); | ||
| 61 | - | ||
| 62 | - /** | ||
| 63 | - * 反审批领料出库单(已审批 → 准备中,恢复库存) | ||
| 64 | - * | ||
| 65 | - * @param id 编号 | ||
| 66 | - */ | ||
| 67 | - void unapproveIssue(Long id); | ||
| 68 | - | ||
| 69 | - /** | ||
| 70 | - * 完成领料出库单(已审批 → 已完成) | 56 | + * 完成领料出库单(草稿 → 已完成,执行出库) |
| 71 | * | 57 | * |
| 72 | * @param id 编号 | 58 | * @param id 编号 |
| 73 | */ | 59 | */ |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java
| @@ -4,14 +4,19 @@ import cn.hutool.core.collection.CollUtil; | @@ -4,14 +4,19 @@ import cn.hutool.core.collection.CollUtil; | ||
| 4 | import cn.hutool.core.util.ObjUtil; | 4 | import cn.hutool.core.util.ObjUtil; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueLineSaveReqVO; | ||
| 7 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssuePageReqVO; | 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssuePageReqVO; |
| 8 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO; | 9 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO; |
| 9 | -import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueLineSaveReqVO; | ||
| 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO; | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO; |
| 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; |
| 12 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper; | 12 | +import cn.iocoder.yudao.module.mes.dal.mysql.md.item.MesMdItemMapper; |
| 13 | +import cn.iocoder.yudao.module.mes.dal.mysql.md.workstation.MesMdWorkstationMapper; | ||
| 14 | +import cn.iocoder.yudao.module.mes.dal.mysql.pro.workorder.MesProWorkOrderMapper; | ||
| 13 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; | 15 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; |
| 16 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper; | ||
| 17 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.warehouse.MesWmWarehouseMapper; | ||
| 14 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductionIssueStatusEnum; | 18 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductionIssueStatusEnum; |
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; | ||
| 15 | import jakarta.annotation.Resource; | 20 | import jakarta.annotation.Resource; |
| 16 | import org.springframework.stereotype.Service; | 21 | import org.springframework.stereotype.Service; |
| 17 | import org.springframework.transaction.annotation.Transactional; | 22 | import org.springframework.transaction.annotation.Transactional; |
| @@ -21,6 +26,11 @@ import java.util.Collection; | @@ -21,6 +26,11 @@ import java.util.Collection; | ||
| 21 | import java.util.Collections; | 26 | import java.util.Collections; |
| 22 | import java.util.List; | 27 | import java.util.List; |
| 23 | 28 | ||
| 29 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 30 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_NOT_EXISTS; | ||
| 31 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_STATUS_INVALID; | ||
| 32 | + | ||
| 33 | +// TODO @AI:参考别的模块,拆分多个; | ||
| 24 | /** | 34 | /** |
| 25 | * MES 领料出库单 Service 实现类 | 35 | * MES 领料出库单 Service 实现类 |
| 26 | */ | 36 | */ |
| @@ -40,17 +50,33 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | @@ -40,17 +50,33 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | ||
| 40 | @Resource | 50 | @Resource |
| 41 | private MesWmProductionIssueDetailService issueDetailService; | 51 | private MesWmProductionIssueDetailService issueDetailService; |
| 42 | 52 | ||
| 53 | + @Resource | ||
| 54 | + private MesWmWarehouseMapper warehouseMapper; | ||
| 55 | + | ||
| 56 | + @Resource | ||
| 57 | + private MesMdItemMapper itemMapper; | ||
| 58 | + | ||
| 59 | + @Resource | ||
| 60 | + private MesMdWorkstationMapper workstationMapper; | ||
| 61 | + | ||
| 62 | + @Resource | ||
| 63 | + private MesProWorkOrderMapper workOrderMapper; | ||
| 64 | + | ||
| 65 | + @Resource | ||
| 66 | + private MesWmMaterialStockService materialStockService; | ||
| 67 | + | ||
| 43 | @Override | 68 | @Override |
| 44 | @Transactional(rollbackFor = Exception.class) | 69 | @Transactional(rollbackFor = Exception.class) |
| 45 | public Long createIssue(MesWmProductionIssueSaveReqVO createReqVO) { | 70 | public Long createIssue(MesWmProductionIssueSaveReqVO createReqVO) { |
| 46 | - // TODO @AI:领料出库关联数据校验待完善(仓库、物料、工单、工位等基础数据校验) | 71 | + // 1. 校验关联数据 |
| 72 | + validateRelatedData(createReqVO); | ||
| 47 | 73 | ||
| 48 | - // 1. 插入主表 | 74 | + // 2. 插入主表 |
| 49 | MesWmProductionIssueDO issueHeader = BeanUtils.toBean(createReqVO, MesWmProductionIssueDO.class); | 75 | MesWmProductionIssueDO issueHeader = BeanUtils.toBean(createReqVO, MesWmProductionIssueDO.class); |
| 50 | issueHeader.setStatus(MesWmProductionIssueStatusEnum.PREPARE.getStatus()); | 76 | issueHeader.setStatus(MesWmProductionIssueStatusEnum.PREPARE.getStatus()); |
| 51 | issueHeaderMapper.insert(issueHeader); | 77 | issueHeaderMapper.insert(issueHeader); |
| 52 | 78 | ||
| 53 | - // 2. 插入行表 | 79 | + // 3. 插入行表 |
| 54 | if (CollUtil.isNotEmpty(createReqVO.getLines())) { | 80 | if (CollUtil.isNotEmpty(createReqVO.getLines())) { |
| 55 | for (MesWmProductionIssueLineSaveReqVO lineVO : createReqVO.getLines()) { | 81 | for (MesWmProductionIssueLineSaveReqVO lineVO : createReqVO.getLines()) { |
| 56 | MesWmProductionIssueLineDO line = BeanUtils.toBean(lineVO, MesWmProductionIssueLineDO.class); | 82 | MesWmProductionIssueLineDO line = BeanUtils.toBean(lineVO, MesWmProductionIssueLineDO.class); |
| @@ -67,13 +93,15 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | @@ -67,13 +93,15 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | ||
| 67 | public void updateIssue(MesWmProductionIssueSaveReqVO updateReqVO) { | 93 | public void updateIssue(MesWmProductionIssueSaveReqVO updateReqVO) { |
| 68 | // 1. 校验存在 + 准备中状态 | 94 | // 1. 校验存在 + 准备中状态 |
| 69 | validateIssueExistsAndPrepare(updateReqVO.getId()); | 95 | validateIssueExistsAndPrepare(updateReqVO.getId()); |
| 70 | - // TODO @AI:领料出库关联数据校验待完善(仓库、物料、工单、工位等基础数据校验) | ||
| 71 | 96 | ||
| 72 | - // 2. 更新主表 | 97 | + // 2. 校验关联数据 |
| 98 | + validateRelatedData(updateReqVO); | ||
| 99 | + | ||
| 100 | + // 3. 更新主表 | ||
| 73 | MesWmProductionIssueDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueDO.class); | 101 | MesWmProductionIssueDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueDO.class); |
| 74 | issueHeaderMapper.updateById(updateObj); | 102 | issueHeaderMapper.updateById(updateObj); |
| 75 | 103 | ||
| 76 | - // 3. 更新行表:先删除旧数据,再插入新数据 | 104 | + // 4. 更新行表:先删除旧数据,再插入新数据 |
| 77 | issueLineMapper.deleteByIssueId(updateReqVO.getId()); | 105 | issueLineMapper.deleteByIssueId(updateReqVO.getId()); |
| 78 | if (CollUtil.isNotEmpty(updateReqVO.getLines())) { | 106 | if (CollUtil.isNotEmpty(updateReqVO.getLines())) { |
| 79 | for (MesWmProductionIssueLineSaveReqVO lineVO : updateReqVO.getLines()) { | 107 | for (MesWmProductionIssueLineSaveReqVO lineVO : updateReqVO.getLines()) { |
| @@ -110,51 +138,33 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | @@ -110,51 +138,33 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | ||
| 110 | 138 | ||
| 111 | @Override | 139 | @Override |
| 112 | @Transactional(rollbackFor = Exception.class) | 140 | @Transactional(rollbackFor = Exception.class) |
| 113 | - public void approveIssue(Long id) { | 141 | + public void finishIssue(Long id) { |
| 114 | // 1.1 校验存在 | 142 | // 1.1 校验存在 |
| 115 | MesWmProductionIssueDO issueHeader = validateIssueExists(id); | 143 | MesWmProductionIssueDO issueHeader = validateIssueExists(id); |
| 116 | - // 1.2 校验状态:只有准备中才允许审批 | 144 | + // 1.2 校验状态:只有草稿才允许完成 |
| 117 | if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issueHeader.getStatus())) { | 145 | if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issueHeader.getStatus())) { |
| 118 | -// throw exception(WM_ISSUE_STATUS_INVALID); | ||
| 119 | - throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下; | ||
| 120 | - } | ||
| 121 | - | ||
| 122 | - // 2. 准备中 → 已审批 | ||
| 123 | - issueHeaderMapper.updateById(new MesWmProductionIssueDO() | ||
| 124 | - .setId(id).setStatus(MesWmProductionIssueStatusEnum.APPROVED.getStatus())); | ||
| 125 | - | ||
| 126 | - // TODO @AI:扣减库存逻辑待完善(需要调用库存服务,根据 detail 表扣减库存) | ||
| 127 | - } | ||
| 128 | - | ||
| 129 | - @Override | ||
| 130 | - @Transactional(rollbackFor = Exception.class) | ||
| 131 | - public void unapproveIssue(Long id) { | ||
| 132 | - // 1.1 校验存在 | ||
| 133 | - MesWmProductionIssueDO issueHeader = validateIssueExists(id); | ||
| 134 | - // 1.2 校验状态:只有已审批才允许反审批 | ||
| 135 | - if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVED.getStatus(), issueHeader.getStatus())) { | ||
| 136 | -// throw exception(WM_ISSUE_STATUS_INVALID); | ||
| 137 | - throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下; | 146 | + throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); |
| 138 | } | 147 | } |
| 139 | 148 | ||
| 140 | - // 2. 已审批 → 准备中 | ||
| 141 | - issueHeaderMapper.updateById(new MesWmProductionIssueDO() | ||
| 142 | - .setId(id).setStatus(MesWmProductionIssueStatusEnum.PREPARE.getStatus())); | ||
| 143 | - | ||
| 144 | - // TODO @AI:恢复库存逻辑待完善(需要调用库存服务,根据 detail 表恢复库存) | ||
| 145 | - } | ||
| 146 | - | ||
| 147 | - @Override | ||
| 148 | - public void finishIssue(Long id) { | ||
| 149 | - // 1.1 校验存在 | ||
| 150 | - MesWmProductionIssueDO issueHeader = validateIssueExists(id); | ||
| 151 | - // 1.2 校验状态:只有已审批才允许完成 | ||
| 152 | - if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVED.getStatus(), issueHeader.getStatus())) { | ||
| 153 | -// throw exception(WM_ISSUE_STATUS_INVALID); | ||
| 154 | - throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下; | 149 | + // 2. 扣减库存(根据 line 表) |
| 150 | + List<MesWmProductionIssueLineDO> lines = issueLineMapper.selectByIssueId(id); | ||
| 151 | + if (CollUtil.isNotEmpty(lines)) { | ||
| 152 | + for (MesWmProductionIssueLineDO line : lines) { | ||
| 153 | + materialStockService.increaseStock( | ||
| 154 | + line.getItemId(), | ||
| 155 | + issueHeader.getWarehouseId(), // 使用主表的仓库ID | ||
| 156 | + null, // locationId | ||
| 157 | + null, // areaId | ||
| 158 | + line.getBatchId(), | ||
| 159 | + line.getQuantityIssued().negate(), // 负数表示扣减 | ||
| 160 | + null, // vendorId | ||
| 161 | + null, // productionDate | ||
| 162 | + null // expireDate | ||
| 163 | + ); | ||
| 164 | + } | ||
| 155 | } | 165 | } |
| 156 | 166 | ||
| 157 | - // 2. 已审批 → 已完成 | 167 | + // 3. 草稿 → 已完成 |
| 158 | issueHeaderMapper.updateById(new MesWmProductionIssueDO() | 168 | issueHeaderMapper.updateById(new MesWmProductionIssueDO() |
| 159 | .setId(id).setStatus(MesWmProductionIssueStatusEnum.FINISHED.getStatus())); | 169 | .setId(id).setStatus(MesWmProductionIssueStatusEnum.FINISHED.getStatus())); |
| 160 | } | 170 | } |
| @@ -170,8 +180,7 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | @@ -170,8 +180,7 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | ||
| 170 | private MesWmProductionIssueDO validateIssueExists(Long id) { | 180 | private MesWmProductionIssueDO validateIssueExists(Long id) { |
| 171 | MesWmProductionIssueDO issueHeader = issueHeaderMapper.selectById(id); | 181 | MesWmProductionIssueDO issueHeader = issueHeaderMapper.selectById(id); |
| 172 | if (issueHeader == null) { | 182 | if (issueHeader == null) { |
| 173 | -// throw exception(WM_ISSUE_NOT_EXISTS); | ||
| 174 | - throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下; | 183 | + throw exception(WM_PRODUCTION_ISSUE_NOT_EXISTS); |
| 175 | } | 184 | } |
| 176 | return issueHeader; | 185 | return issueHeader; |
| 177 | } | 186 | } |
| @@ -182,8 +191,7 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | @@ -182,8 +191,7 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ | ||
| 182 | private MesWmProductionIssueDO validateIssueExistsAndPrepare(Long id) { | 191 | private MesWmProductionIssueDO validateIssueExistsAndPrepare(Long id) { |
| 183 | MesWmProductionIssueDO issueHeader = validateIssueExists(id); | 192 | MesWmProductionIssueDO issueHeader = validateIssueExists(id); |
| 184 | if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issueHeader.getStatus())) { | 193 | if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issueHeader.getStatus())) { |
| 185 | -// throw exception(WM_ISSUE_STATUS_INVALID); | ||
| 186 | - throw new IllegalArgumentException(); // TODO @芋艿:晚点优化下; | 194 | + throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); |
| 187 | } | 195 | } |
| 188 | return issueHeader; | 196 | return issueHeader; |
| 189 | } | 197 | } |