Commit efde91601411e758e623ad950e865b3b14ddcf38
1 parent
8d2fc22d
✨ feat(mes): 添加生产领料出库单相关功能与接口
新增生产领料出库单的状态管理、行验证及明细查询功能,优化了相关数据模型和接口,提升了系统的可用性和用户体验。
Showing
18 changed files
with
262 additions
and
131 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/MesWmProductionIssueController.java
| ... | ... | @@ -109,13 +109,40 @@ public class MesWmProductionIssueController { |
| 109 | 109 | @PutMapping("/finish") |
| 110 | 110 | @Operation(summary = "完成领料出库单") |
| 111 | 111 | @Parameter(name = "id", description = "编号", required = true) |
| 112 | - @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update-status')") | |
| 112 | + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:execute')") | |
| 113 | 113 | public CommonResult<Boolean> finishProductionIssue(@RequestParam("id") Long id) { |
| 114 | 114 | issueService.finishProductionIssue(id); |
| 115 | 115 | return success(true); |
| 116 | 116 | } |
| 117 | 117 | |
| 118 | - // TODO @AI:check quantity | |
| 118 | + @PutMapping("/submit") | |
| 119 | + @Operation(summary = "提交领料出库单") | |
| 120 | + @Parameter(name = "id", description = "编号", required = true) | |
| 121 | + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')") | |
| 122 | + public CommonResult<Boolean> submitProductionIssue(@RequestParam("id") Long id) { | |
| 123 | + issueService.submitProductionIssue(id); | |
| 124 | + return success(true); | |
| 125 | + } | |
| 126 | + | |
| 127 | + @PutMapping("/stock") | |
| 128 | + @Operation(summary = "执行拣货") | |
| 129 | + @Parameter(name = "id", description = "编号", required = true) | |
| 130 | + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')") | |
| 131 | + public CommonResult<Boolean> stockProductionIssue(@RequestParam("id") Long id) { | |
| 132 | + issueService.stockProductionIssue(id); | |
| 133 | + return success(true); | |
| 134 | + } | |
| 135 | + | |
| 136 | + @PutMapping("/cancel") | |
| 137 | + @Operation(summary = "取消领料出库单") | |
| 138 | + @Parameter(name = "id", description = "编号", required = true) | |
| 139 | + @PreAuthorize("@ss.hasPermission('mes:wm-production-issue:update')") | |
| 140 | + public CommonResult<Boolean> cancelProductionIssue(@RequestParam("id") Long id) { | |
| 141 | + issueService.cancelProductionIssue(id); | |
| 142 | + return success(true); | |
| 143 | + } | |
| 144 | + | |
| 145 | + // TODO @AI:【芋艿】check quantity;晚点搞; | |
| 119 | 146 | |
| 120 | 147 | // ==================== 拼接 VO ==================== |
| 121 | 148 | |
| ... | ... | @@ -127,15 +154,15 @@ public class MesWmProductionIssueController { |
| 127 | 154 | Map<Long, MesMdWorkstationDO> workstationMap = workstationService.getWorkstationMap( |
| 128 | 155 | convertSet(list, MesWmProductionIssueDO::getWorkstationId)); |
| 129 | 156 | Map<Long, MesProWorkOrderDO> workOrderMap = workOrderService.getWorkOrderMap( |
| 130 | - convertSet(list, MesWmProductionIssueDO::getWorkorderId)); | |
| 157 | + convertSet(list, MesWmProductionIssueDO::getWorkOrderId)); | |
| 131 | 158 | // 2. 构建结果 |
| 132 | 159 | return BeanUtils.toBean(list, MesWmProductionIssueRespVO.class, vo -> { |
| 133 | 160 | // 2.1 填充工作站名称 |
| 134 | 161 | MapUtils.findAndThen(workstationMap, vo.getWorkstationId(), |
| 135 | 162 | workstation -> vo.setWorkstationName(workstation.getName())); |
| 136 | 163 | // 2.2 填充工单编号 |
| 137 | - MapUtils.findAndThen(workOrderMap, vo.getWorkorderId(), | |
| 138 | - workOrder -> vo.setWorkorderCode(workOrder.getCode())); | |
| 164 | + MapUtils.findAndThen(workOrderMap, vo.getWorkOrderId(), | |
| 165 | + workOrder -> vo.setWorkOrderCode(workOrder.getCode())); | |
| 139 | 166 | }); |
| 140 | 167 | } |
| 141 | 168 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssuePageReqVO.java
| ... | ... | @@ -25,7 +25,7 @@ public class MesWmProductionIssuePageReqVO extends PageParam { |
| 25 | 25 | private Long workstationId; |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "生产工单ID", example = "1") |
| 28 | - private Long workorderId; | |
| 28 | + private Long workOrderId; | |
| 29 | 29 | |
| 30 | 30 | @Schema(description = "生产任务ID", example = "1") |
| 31 | 31 | private Long taskId; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueRespVO.java
| ... | ... | @@ -25,10 +25,10 @@ public class MesWmProductionIssueRespVO { |
| 25 | 25 | private String workstationName; |
| 26 | 26 | |
| 27 | 27 | @Schema(description = "生产工单 ID", example = "1") |
| 28 | - private Long workorderId; | |
| 28 | + private Long workOrderId; | |
| 29 | 29 | |
| 30 | 30 | @Schema(description = "生产工单编号", example = "WO20250226001") |
| 31 | - private String workorderCode; | |
| 31 | + private String workOrderCode; | |
| 32 | 32 | |
| 33 | 33 | @Schema(description = "生产任务 ID", example = "1") |
| 34 | 34 | private Long taskId; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/MesWmProductionIssueSaveReqVO.java
| ... | ... | @@ -23,11 +23,12 @@ public class MesWmProductionIssueSaveReqVO { |
| 23 | 23 | private String name; |
| 24 | 24 | |
| 25 | 25 | @Schema(description = "工作站 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 26 | - @NotNull(message = "工作站ID不能为空") | |
| 26 | + @NotNull(message = "工作站 ID 不能为空") | |
| 27 | 27 | private Long workstationId; |
| 28 | 28 | |
| 29 | - @Schema(description = "生产工单 ID", example = "1") | |
| 30 | - private Long workorderId; | |
| 29 | + @Schema(description = "生产工单 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 30 | + @NotNull(message = "生产工单 ID 不能为空") | |
| 31 | + private Long workOrderId; | |
| 31 | 32 | |
| 32 | 33 | @Schema(description = "需求时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 33 | 34 | @NotNull(message = "需求时间不能为空") | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/productionissue/vo/line/MesWmProductionIssueLineSaveReqVO.java
| ... | ... | @@ -12,6 +12,9 @@ public class MesWmProductionIssueLineSaveReqVO { |
| 12 | 12 | @Schema(description = "行ID", example = "1") |
| 13 | 13 | private Long id; |
| 14 | 14 | |
| 15 | + @Schema(description = "领料单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 16 | + private Long issueId; | |
| 17 | + | |
| 15 | 18 | @Schema(description = "物料ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 16 | 19 | private Long itemId; |
| 17 | 20 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDO.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | -import cn.iocoder.yudao.module.mes.dal.dataobject.md.client.MesMdClientDO; | |
| 5 | 4 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.workstation.MesMdWorkstationDO; |
| 6 | 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.task.MesProTaskDO; |
| 7 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.pro.workorder.MesProWorkOrderDO; |
| ... | ... | @@ -13,12 +12,11 @@ import lombok.*; |
| 13 | 12 | |
| 14 | 13 | import java.time.LocalDateTime; |
| 15 | 14 | |
| 16 | -// TODO @AI:【需要一起讨论】不要直接改;是不是叫 issueheader 包?主要后续别的表也有 issue,希望区分下;还是加个合理的前缀?就像 wm_outsource_issue 这种; | |
| 17 | 15 | /** |
| 18 | 16 | * MES 领料出库单 DO |
| 19 | 17 | */ |
| 20 | -@TableName("mes_wm_issue_header") | |
| 21 | -@KeySequence("mes_wm_issue_header_seq") | |
| 18 | +@TableName("mes_wm_production_issue") | |
| 19 | +@KeySequence("mes_wm_production_issue_seq") | |
| 22 | 20 | @Data |
| 23 | 21 | @EqualsAndHashCode(callSuper = true) |
| 24 | 22 | @ToString(callSuper = true) |
| ... | ... | @@ -46,28 +44,20 @@ public class MesWmProductionIssueDO extends BaseDO { |
| 46 | 44 | * 关联 {@link MesMdWorkstationDO#getId()} |
| 47 | 45 | */ |
| 48 | 46 | private Long workstationId; |
| 49 | - // TODO @AI:workOrderId; | |
| 50 | 47 | /** |
| 51 | 48 | * 生产工单 ID |
| 52 | 49 | * |
| 53 | 50 | * 关联 {@link MesProWorkOrderDO#getId()} |
| 54 | 51 | */ |
| 55 | - private Long workorderId; | |
| 56 | - // TODO @芋艿:【疑问】这个字段的来源? | |
| 52 | + private Long workOrderId; | |
| 53 | + // TODO @芋艿:【疑问,不要动】这个字段的来源? | |
| 57 | 54 | /** |
| 58 | 55 | * 生产任务 ID |
| 59 | 56 | * |
| 60 | 57 | * 关联 {@link MesProTaskDO#getId()} |
| 61 | 58 | */ |
| 62 | 59 | private Long taskId; |
| 63 | - // TODO @AI:应该不用记录?因为 workorderId 字段的; | |
| 64 | - /** | |
| 65 | - * 客户 ID | |
| 66 | - * | |
| 67 | - * 关联 {@link MesMdClientDO#getId()} | |
| 68 | - */ | |
| 69 | - private Long clientId; | |
| 70 | - // TODO @芋艿:【疑问】这个字段的更新时间; | |
| 60 | + // TODO @芋艿:【疑问,不要动】这个字段的更新时间; | |
| 71 | 61 | /** |
| 72 | 62 | * 领料日期 |
| 73 | 63 | */ |
| ... | ... | @@ -86,21 +76,5 @@ public class MesWmProductionIssueDO extends BaseDO { |
| 86 | 76 | * 备注 |
| 87 | 77 | */ |
| 88 | 78 | private String remark; |
| 89 | - /** | |
| 90 | - * 预留字段 1 | |
| 91 | - */ | |
| 92 | - private String attribute1; | |
| 93 | - /** | |
| 94 | - * 预留字段 2 | |
| 95 | - */ | |
| 96 | - private String attribute2; | |
| 97 | - /** | |
| 98 | - * 预留字段 3 | |
| 99 | - */ | |
| 100 | - private Integer attribute3; | |
| 101 | - /** | |
| 102 | - * 预留字段 4 | |
| 103 | - */ | |
| 104 | - private Integer attribute4; | |
| 105 | 79 | |
| 106 | 80 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueDetailDO.java
| ... | ... | @@ -16,8 +16,8 @@ import java.math.BigDecimal; |
| 16 | 16 | /** |
| 17 | 17 | * MES 领料出库明细 DO |
| 18 | 18 | */ |
| 19 | -@TableName("mes_wm_issue_detail") | |
| 20 | -@KeySequence("mes_wm_issue_detail_seq") | |
| 19 | +@TableName("mes_wm_production_issue_detail") | |
| 20 | +@KeySequence("mes_wm_production_issue_detail_seq") | |
| 21 | 21 | @Data |
| 22 | 22 | @EqualsAndHashCode(callSuper = true) |
| 23 | 23 | @ToString(callSuper = true) |
| ... | ... | @@ -85,21 +85,5 @@ public class MesWmProductionIssueDetailDO extends BaseDO { |
| 85 | 85 | * 备注 |
| 86 | 86 | */ |
| 87 | 87 | private String remark; |
| 88 | - /** | |
| 89 | - * 预留字段1 | |
| 90 | - */ | |
| 91 | - private String attribute1; | |
| 92 | - /** | |
| 93 | - * 预留字段2 | |
| 94 | - */ | |
| 95 | - private String attribute2; | |
| 96 | - /** | |
| 97 | - * 预留字段3 | |
| 98 | - */ | |
| 99 | - private Integer attribute3; | |
| 100 | - /** | |
| 101 | - * 预留字段4 | |
| 102 | - */ | |
| 103 | - private Integer attribute4; | |
| 104 | 88 | |
| 105 | 89 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productionissue/MesWmProductionIssueLineDO.java
| ... | ... | @@ -12,8 +12,8 @@ import java.math.BigDecimal; |
| 12 | 12 | /** |
| 13 | 13 | * MES 领料出库单行 DO |
| 14 | 14 | */ |
| 15 | -@TableName("mes_wm_issue_line") | |
| 16 | -@KeySequence("mes_wm_issue_line_seq") | |
| 15 | +@TableName("mes_wm_production_issue_line") | |
| 16 | +@KeySequence("mes_wm_production_issue_line_seq") | |
| 17 | 17 | @Data |
| 18 | 18 | @EqualsAndHashCode(callSuper = true) |
| 19 | 19 | @ToString(callSuper = true) |
| ... | ... | @@ -51,21 +51,5 @@ public class MesWmProductionIssueLineDO extends BaseDO { |
| 51 | 51 | * 备注 |
| 52 | 52 | */ |
| 53 | 53 | private String remark; |
| 54 | - /** | |
| 55 | - * 预留字段 1 | |
| 56 | - */ | |
| 57 | - private String attribute1; | |
| 58 | - /** | |
| 59 | - * 预留字段 2 | |
| 60 | - */ | |
| 61 | - private String attribute2; | |
| 62 | - /** | |
| 63 | - * 预留字段 3 | |
| 64 | - */ | |
| 65 | - private Integer attribute3; | |
| 66 | - /** | |
| 67 | - * 预留字段 4 | |
| 68 | - */ | |
| 69 | - private Integer attribute4; | |
| 70 | 54 | |
| 71 | 55 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueDetailMapper.java
| ... | ... | @@ -16,6 +16,10 @@ public interface MesWmProductionIssueDetailMapper extends BaseMapperX<MesWmProdu |
| 16 | 16 | return selectList(MesWmProductionIssueDetailDO::getLineId, lineId); |
| 17 | 17 | } |
| 18 | 18 | |
| 19 | + default List<MesWmProductionIssueDetailDO> selectListByIssueId(Long issueId) { | |
| 20 | + return selectList(MesWmProductionIssueDetailDO::getIssueId, issueId); | |
| 21 | + } | |
| 22 | + | |
| 19 | 23 | default void deleteByIssueId(Long issueId) { |
| 20 | 24 | delete(MesWmProductionIssueDetailDO::getIssueId, issueId); |
| 21 | 25 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/mysql/wm/productionissue/MesWmProductionIssueMapper.java
| ... | ... | @@ -18,9 +18,7 @@ public interface MesWmProductionIssueMapper extends BaseMapperX<MesWmProductionI |
| 18 | 18 | .likeIfPresent(MesWmProductionIssueDO::getCode, reqVO.getCode()) |
| 19 | 19 | .likeIfPresent(MesWmProductionIssueDO::getName, reqVO.getName()) |
| 20 | 20 | .eqIfPresent(MesWmProductionIssueDO::getWorkstationId, reqVO.getWorkstationId()) |
| 21 | - .eqIfPresent(MesWmProductionIssueDO::getWorkorderId, reqVO.getWorkorderId()) | |
| 22 | - .eqIfPresent(MesWmProductionIssueDO::getTaskId, reqVO.getTaskId()) | |
| 23 | - .eqIfPresent(MesWmProductionIssueDO::getClientId, reqVO.getClientId()) | |
| 21 | + .eqIfPresent(MesWmProductionIssueDO::getWorkOrderId, reqVO.getWorkOrderId()) | |
| 24 | 22 | .eqIfPresent(MesWmProductionIssueDO::getStatus, reqVO.getStatus()) |
| 25 | 23 | .betweenIfPresent(MesWmProductionIssueDO::getIssueDate, reqVO.getIssueDate()) |
| 26 | 24 | .orderByDesc(MesWmProductionIssueDO::getId)); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| ... | ... | @@ -360,9 +360,11 @@ public interface ErrorCodeConstants { |
| 360 | 360 | // ========== MES 仓库管理-生产领料出库单(1-040-708-000) ========== |
| 361 | 361 | ErrorCode WM_PRODUCTION_ISSUE_NOT_EXISTS = new ErrorCode(1_040_708_000, "生产领料出库单不存在"); |
| 362 | 362 | ErrorCode WM_PRODUCTION_ISSUE_STATUS_INVALID = new ErrorCode(1_040_708_001, "生产领料出库单状态不正确,无法执行该操作"); |
| 363 | - // DONE @AI:不需要的错误码,需要处理下 - 已删除不需要的错误码(WM_PRODUCTION_ISSUE_WAREHOUSE_NOT_EXISTS, WM_PRODUCTION_ISSUE_ITEM_NOT_EXISTS, WM_PRODUCTION_ISSUE_NO_LINE, WM_PRODUCTION_ISSUE_QUANTITY_MISMATCH),保留需要的错误码 | |
| 363 | + ErrorCode WM_PRODUCTION_ISSUE_NO_LINE = new ErrorCode(1_040_708_002, "生产领料出库单至少需要一条行数据"); | |
| 364 | + ErrorCode WM_PRODUCTION_ISSUE_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_708_003, "领料出库单行数量与明细数量不一致"); | |
| 364 | 365 | ErrorCode WM_PRODUCTION_ISSUE_WORKORDER_NOT_EXISTS = new ErrorCode(1_040_708_004, "生产工单不存在"); |
| 365 | 366 | ErrorCode WM_PRODUCTION_ISSUE_WORKSTATION_NOT_EXISTS = new ErrorCode(1_040_708_005, "工作站不存在"); |
| 367 | + ErrorCode WM_PRODUCTION_ISSUE_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_708_006, "生产领料出库单已完成或已取消,无法取消"); | |
| 366 | 368 | ErrorCode WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS = new ErrorCode(1_040_708_100, "生产领料出库单行不存在"); |
| 367 | 369 | ErrorCode WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS = new ErrorCode(1_040_708_200, "生产领料出库单明细不存在"); |
| 368 | 370 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductionIssueStatusEnum.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.enums.wm; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.core.ArrayValuable; |
| 4 | +import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO; | |
| 4 | 5 | import cn.iocoder.yudao.module.mes.enums.MesOrderStatusConstants; |
| 6 | +import cn.iocoder.yudao.module.mes.service.wm.productionissue.MesWmProductionIssueService; | |
| 5 | 7 | import lombok.AllArgsConstructor; |
| 6 | 8 | import lombok.Getter; |
| 7 | 9 | |
| ... | ... | @@ -9,18 +11,48 @@ import java.util.Arrays; |
| 9 | 11 | |
| 10 | 12 | /** |
| 11 | 13 | * MES 领料出库单状态枚举 |
| 14 | + * | |
| 15 | + * @author 芋道源码 | |
| 12 | 16 | */ |
| 13 | 17 | @Getter |
| 14 | 18 | @AllArgsConstructor |
| 15 | 19 | public enum MesWmProductionIssueStatusEnum implements ArrayValuable<Integer> { |
| 16 | 20 | |
| 21 | + /** | |
| 22 | + * 草稿 | |
| 23 | + * | |
| 24 | + * 对应方法:{@link MesWmProductionIssueService#createProductionIssue(MesWmProductionIssueSaveReqVO)} | |
| 25 | + */ | |
| 17 | 26 | PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), |
| 18 | - FINISHED(MesOrderStatusConstants.FINISHED, "已完成"); | |
| 27 | + /** | |
| 28 | + * 待拣货 | |
| 29 | + * | |
| 30 | + * 对应方法:{@link MesWmProductionIssueService#submitProductionIssue(Long)} | |
| 31 | + */ | |
| 32 | + APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"), | |
| 33 | + /** | |
| 34 | + * 待执行领出 | |
| 35 | + * | |
| 36 | + * 对应方法:{@link MesWmProductionIssueService#stockProductionIssue(Long)} | |
| 37 | + */ | |
| 38 | + APPROVED(MesOrderStatusConstants.APPROVED, "待执行领出"), | |
| 39 | + /** | |
| 40 | + * 已完成 | |
| 41 | + * | |
| 42 | + * 对应方法:{@link MesWmProductionIssueService#finishProductionIssue(Long)} | |
| 43 | + */ | |
| 44 | + FINISHED(MesOrderStatusConstants.FINISHED, "已完成"), | |
| 45 | + /** | |
| 46 | + * 已取消 | |
| 47 | + * | |
| 48 | + * 对应方法:{@link MesWmProductionIssueService#cancelProductionIssue(Long)} | |
| 49 | + */ | |
| 50 | + CANCELED(MesOrderStatusConstants.CANCELLED, "已取消"); | |
| 19 | 51 | |
| 20 | 52 | public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmProductionIssueStatusEnum::getStatus).toArray(Integer[]::new); |
| 21 | 53 | |
| 22 | 54 | /** |
| 23 | - * 状态 | |
| 55 | + * 状态值 | |
| 24 | 56 | */ |
| 25 | 57 | private final Integer status; |
| 26 | 58 | /** | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailService.java
| ... | ... | @@ -50,6 +50,14 @@ public interface MesWmProductionIssueDetailService { |
| 50 | 50 | List<MesWmProductionIssueDetailDO> getProductionIssueDetailListByLineId(Long lineId); |
| 51 | 51 | |
| 52 | 52 | /** |
| 53 | + * 根据领料单ID获取明细列表 | |
| 54 | + * | |
| 55 | + * @param issueId 领料单ID | |
| 56 | + * @return 明细列表 | |
| 57 | + */ | |
| 58 | + List<MesWmProductionIssueDetailDO> getProductionIssueDetailListByIssueId(Long issueId); | |
| 59 | + | |
| 60 | + /** | |
| 53 | 61 | * 根据领料单ID删除明细 |
| 54 | 62 | * |
| 55 | 63 | * @param issueId 领料单ID | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueDetailServiceImpl.java
| ... | ... | @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 4 | 4 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.detail.MesWmProductionIssueDetailSaveReqVO; |
| 5 | 5 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO; |
| 6 | 6 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueDetailMapper; |
| 7 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; | |
| 8 | 7 | import jakarta.annotation.Resource; |
| 8 | +import org.springframework.context.annotation.Lazy; | |
| 9 | 9 | import org.springframework.stereotype.Service; |
| 10 | 10 | import org.springframework.validation.annotation.Validated; |
| 11 | 11 | |
| ... | ... | @@ -13,7 +13,6 @@ import java.util.List; |
| 13 | 13 | |
| 14 | 14 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 15 | 15 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS; |
| 16 | -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS; | |
| 17 | 16 | |
| 18 | 17 | /** |
| 19 | 18 | * MES 领料出库明细 Service 实现类 |
| ... | ... | @@ -24,13 +23,15 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss |
| 24 | 23 | |
| 25 | 24 | @Resource |
| 26 | 25 | private MesWmProductionIssueDetailMapper issueDetailMapper; |
| 26 | + | |
| 27 | 27 | @Resource |
| 28 | - private MesWmProductionIssueLineMapper issueLineMapper; | |
| 28 | + @Lazy | |
| 29 | + private MesWmProductionIssueLineService issueLineService; | |
| 29 | 30 | |
| 30 | 31 | @Override |
| 31 | 32 | public Long createProductionIssueDetail(MesWmProductionIssueDetailSaveReqVO createReqVO) { |
| 32 | 33 | // 校验父数据存在 |
| 33 | - validateParentIssueLineExists(createReqVO.getLineId()); | |
| 34 | + issueLineService.validateProductionIssueLineExists(createReqVO.getLineId()); | |
| 34 | 35 | |
| 35 | 36 | // 插入 |
| 36 | 37 | MesWmProductionIssueDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductionIssueDetailDO.class); |
| ... | ... | @@ -41,9 +42,9 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss |
| 41 | 42 | @Override |
| 42 | 43 | public void updateProductionIssueDetail(MesWmProductionIssueDetailSaveReqVO updateReqVO) { |
| 43 | 44 | // 校验存在 |
| 44 | - validateIssueDetailExists(updateReqVO.getId()); | |
| 45 | + validateProductionIssueDetailExists(updateReqVO.getId()); | |
| 45 | 46 | // 校验父数据存在 |
| 46 | - validateParentIssueLineExists(updateReqVO.getLineId()); | |
| 47 | + issueLineService.validateProductionIssueLineExists(updateReqVO.getLineId()); | |
| 47 | 48 | |
| 48 | 49 | // 更新 |
| 49 | 50 | MesWmProductionIssueDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueDetailDO.class); |
| ... | ... | @@ -53,7 +54,7 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss |
| 53 | 54 | @Override |
| 54 | 55 | public void deleteProductionIssueDetail(Long id) { |
| 55 | 56 | // 校验存在 |
| 56 | - validateIssueDetailExists(id); | |
| 57 | + validateProductionIssueDetailExists(id); | |
| 57 | 58 | // 删除 |
| 58 | 59 | issueDetailMapper.deleteById(id); |
| 59 | 60 | } |
| ... | ... | @@ -69,20 +70,19 @@ public class MesWmProductionIssueDetailServiceImpl implements MesWmProductionIss |
| 69 | 70 | } |
| 70 | 71 | |
| 71 | 72 | @Override |
| 73 | + public List<MesWmProductionIssueDetailDO> getProductionIssueDetailListByIssueId(Long issueId) { | |
| 74 | + return issueDetailMapper.selectListByIssueId(issueId); | |
| 75 | + } | |
| 76 | + | |
| 77 | + @Override | |
| 72 | 78 | public void deleteProductionIssueDetailByIssueId(Long issueId) { |
| 73 | 79 | issueDetailMapper.deleteByIssueId(issueId); |
| 74 | 80 | } |
| 75 | 81 | |
| 76 | - private void validateIssueDetailExists(Long id) { | |
| 82 | + private void validateProductionIssueDetailExists(Long id) { | |
| 77 | 83 | if (issueDetailMapper.selectById(id) == null) { |
| 78 | 84 | throw exception(WM_PRODUCTION_ISSUE_DETAIL_NOT_EXISTS); |
| 79 | 85 | } |
| 80 | 86 | } |
| 81 | 87 | |
| 82 | - private void validateParentIssueLineExists(Long lineId) { | |
| 83 | - if (issueLineMapper.selectById(lineId) == null) { | |
| 84 | - throw exception(WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS); | |
| 85 | - } | |
| 86 | - } | |
| 87 | - | |
| 88 | 88 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineService.java
| ... | ... | @@ -66,4 +66,12 @@ public interface MesWmProductionIssueLineService { |
| 66 | 66 | */ |
| 67 | 67 | void deleteProductionIssueLineByIssueId(Long issueId); |
| 68 | 68 | |
| 69 | + /** | |
| 70 | + * 校验领料出库单行是否存在 | |
| 71 | + * | |
| 72 | + * @param id 编号 | |
| 73 | + * @return 领料出库单行 | |
| 74 | + */ | |
| 75 | + MesWmProductionIssueLineDO validateProductionIssueLineExists(Long id); | |
| 76 | + | |
| 69 | 77 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueLineServiceImpl.java
| ... | ... | @@ -6,8 +6,9 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.M |
| 6 | 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.line.MesWmProductionIssueLineSaveReqVO; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; |
| 8 | 8 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueLineMapper; |
| 9 | -import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper; | |
| 9 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 10 | 10 | import jakarta.annotation.Resource; |
| 11 | +import org.springframework.context.annotation.Lazy; | |
| 11 | 12 | import org.springframework.stereotype.Service; |
| 12 | 13 | import org.springframework.validation.annotation.Validated; |
| 13 | 14 | |
| ... | ... | @@ -15,7 +16,6 @@ import java.util.List; |
| 15 | 16 | |
| 16 | 17 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 17 | 18 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS; |
| 18 | -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCTION_ISSUE_NOT_EXISTS; | |
| 19 | 19 | |
| 20 | 20 | /** |
| 21 | 21 | * MES 领料出库单行 Service 实现类 |
| ... | ... | @@ -26,13 +26,19 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue |
| 26 | 26 | |
| 27 | 27 | @Resource |
| 28 | 28 | private MesWmProductionIssueLineMapper issueLineMapper; |
| 29 | + | |
| 30 | + @Resource | |
| 31 | + @Lazy | |
| 32 | + private MesWmProductionIssueService issueService; | |
| 29 | 33 | @Resource |
| 30 | - private MesWmProductionIssueMapper issueMapper; | |
| 34 | + private MesMdItemService itemService; | |
| 31 | 35 | |
| 32 | 36 | @Override |
| 33 | 37 | public Long createProductionIssueLine(MesWmProductionIssueLineSaveReqVO createReqVO) { |
| 34 | 38 | // 校验父数据存在 |
| 35 | - validateParentIssueExists(createReqVO.getIssueId()); | |
| 39 | + issueService.validateProductionIssueExists(createReqVO.getIssueId()); | |
| 40 | + // 校验物料存在 | |
| 41 | + itemService.validateItemExists(createReqVO.getItemId()); | |
| 36 | 42 | |
| 37 | 43 | // 插入 |
| 38 | 44 | MesWmProductionIssueLineDO line = BeanUtils.toBean(createReqVO, MesWmProductionIssueLineDO.class); |
| ... | ... | @@ -43,9 +49,11 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue |
| 43 | 49 | @Override |
| 44 | 50 | public void updateProductionIssueLine(MesWmProductionIssueLineSaveReqVO updateReqVO) { |
| 45 | 51 | // 校验存在 |
| 46 | - validateIssueLineExists(updateReqVO.getId()); | |
| 52 | + validateProductionIssueLineExists(updateReqVO.getId()); | |
| 47 | 53 | // 校验父数据存在 |
| 48 | - validateParentIssueExists(updateReqVO.getIssueId()); | |
| 54 | + issueService.validateProductionIssueExists(updateReqVO.getIssueId()); | |
| 55 | + // 校验物料存在 | |
| 56 | + itemService.validateItemExists(updateReqVO.getItemId()); | |
| 49 | 57 | |
| 50 | 58 | // 更新 |
| 51 | 59 | MesWmProductionIssueLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductionIssueLineDO.class); |
| ... | ... | @@ -55,7 +63,7 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue |
| 55 | 63 | @Override |
| 56 | 64 | public void deleteProductionIssueLine(Long id) { |
| 57 | 65 | // 校验存在 |
| 58 | - validateIssueLineExists(id); | |
| 66 | + validateProductionIssueLineExists(id); | |
| 59 | 67 | // 删除 |
| 60 | 68 | issueLineMapper.deleteById(id); |
| 61 | 69 | } |
| ... | ... | @@ -80,16 +88,13 @@ public class MesWmProductionIssueLineServiceImpl implements MesWmProductionIssue |
| 80 | 88 | issueLineMapper.deleteByIssueId(issueId); |
| 81 | 89 | } |
| 82 | 90 | |
| 83 | - private void validateIssueLineExists(Long id) { | |
| 84 | - if (issueLineMapper.selectById(id) == null) { | |
| 91 | + @Override | |
| 92 | + public MesWmProductionIssueLineDO validateProductionIssueLineExists(Long id) { | |
| 93 | + MesWmProductionIssueLineDO line = issueLineMapper.selectById(id); | |
| 94 | + if (line == null) { | |
| 85 | 95 | throw exception(WM_PRODUCTION_ISSUE_LINE_NOT_EXISTS); |
| 86 | 96 | } |
| 87 | - } | |
| 88 | - | |
| 89 | - private void validateParentIssueExists(Long issueId) { | |
| 90 | - if (issueMapper.selectById(issueId) == null) { | |
| 91 | - throw exception(WM_PRODUCTION_ISSUE_NOT_EXISTS); | |
| 92 | - } | |
| 97 | + return line; | |
| 93 | 98 | } |
| 94 | 99 | |
| 95 | 100 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueService.java
| ... | ... | @@ -50,10 +50,39 @@ public interface MesWmProductionIssueService { |
| 50 | 50 | PageResult<MesWmProductionIssueDO> getProductionIssuePage(MesWmProductionIssuePageReqVO pageReqVO); |
| 51 | 51 | |
| 52 | 52 | /** |
| 53 | - * 完成领料出库单(草稿 → 已完成,执行出库) | |
| 53 | + * 校验领料出库单是否存在 | |
| 54 | + * | |
| 55 | + * @param id 编号 | |
| 56 | + * @return 领料出库单 | |
| 57 | + */ | |
| 58 | + MesWmProductionIssueDO validateProductionIssueExists(Long id); | |
| 59 | + | |
| 60 | + /** | |
| 61 | + * 提交领料出库单(草稿 → 待拣货) | |
| 62 | + * | |
| 63 | + * @param id 编号 | |
| 64 | + */ | |
| 65 | + void submitProductionIssue(Long id); | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * 执行拣货(待拣货 → 待执行领出) | |
| 69 | + * | |
| 70 | + * @param id 编号 | |
| 71 | + */ | |
| 72 | + void stockProductionIssue(Long id); | |
| 73 | + | |
| 74 | + /** | |
| 75 | + * 执行领出/出库(待执行领出 → 已完成),更新库存台账 | |
| 54 | 76 | * |
| 55 | 77 | * @param id 编号 |
| 56 | 78 | */ |
| 57 | 79 | void finishProductionIssue(Long id); |
| 58 | 80 | |
| 81 | + /** | |
| 82 | + * 取消领料出库单(任意非已完成/已取消状态 → 已取消) | |
| 83 | + * | |
| 84 | + * @param id 编号 | |
| 85 | + */ | |
| 86 | + void cancelProductionIssue(Long id); | |
| 87 | + | |
| 59 | 88 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productionissue/MesWmProductionIssueServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.productionissue; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.hutool.core.util.ObjUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | 7 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 8 | +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; | |
| 6 | 9 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssuePageReqVO; |
| 7 | 10 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productionissue.vo.MesWmProductionIssueSaveReqVO; |
| 11 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDetailDO; | |
| 8 | 12 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueDO; |
| 13 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productionissue.MesWmProductionIssueLineDO; | |
| 9 | 14 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productionissue.MesWmProductionIssueMapper; |
| 10 | 15 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductionIssueStatusEnum; |
| 11 | 16 | import cn.iocoder.yudao.module.mes.service.md.workstation.MesMdWorkstationService; |
| ... | ... | @@ -15,6 +20,9 @@ import org.springframework.stereotype.Service; |
| 15 | 20 | import org.springframework.transaction.annotation.Transactional; |
| 16 | 21 | import org.springframework.validation.annotation.Validated; |
| 17 | 22 | |
| 23 | +import java.math.BigDecimal; | |
| 24 | +import java.util.List; | |
| 25 | + | |
| 18 | 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 19 | 27 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*; |
| 20 | 28 | |
| ... | ... | @@ -41,9 +49,9 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ |
| 41 | 49 | @Transactional(rollbackFor = Exception.class) |
| 42 | 50 | public Long createProductionIssue(MesWmProductionIssueSaveReqVO createReqVO) { |
| 43 | 51 | // 1. 校验关联数据 |
| 44 | - workstationService.validateWorkstationExists(createReqVO.getWorkstationId()); | |
| 45 | - if (createReqVO.getWorkorderId() != null) { | |
| 46 | - workOrderService.validateWorkOrderExists(createReqVO.getWorkorderId()); | |
| 52 | + workOrderService.validateWorkOrderExists(createReqVO.getWorkOrderId()); | |
| 53 | + if (createReqVO.getWorkstationId() != null) { | |
| 54 | + workstationService.validateWorkstationExists(createReqVO.getWorkstationId()); | |
| 47 | 55 | } |
| 48 | 56 | |
| 49 | 57 | // 2. 插入主表 |
| ... | ... | @@ -57,11 +65,11 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ |
| 57 | 65 | @Transactional(rollbackFor = Exception.class) |
| 58 | 66 | public void updateProductionIssue(MesWmProductionIssueSaveReqVO updateReqVO) { |
| 59 | 67 | // 1.1 校验存在 + 准备中状态 |
| 60 | - validateIssueExistsAndPrepare(updateReqVO.getId()); | |
| 68 | + validateProductionIssueExistsAndPrepare(updateReqVO.getId()); | |
| 61 | 69 | // 1.2 校验关联数据 |
| 62 | - workstationService.validateWorkstationExists(updateReqVO.getWorkstationId()); | |
| 63 | - if (updateReqVO.getWorkorderId() != null) { | |
| 64 | - workOrderService.validateWorkOrderExists(updateReqVO.getWorkorderId()); | |
| 70 | + workOrderService.validateWorkOrderExists(updateReqVO.getWorkOrderId()); | |
| 71 | + if (updateReqVO.getWorkstationId() != null) { | |
| 72 | + workstationService.validateWorkstationExists(updateReqVO.getWorkstationId()); | |
| 65 | 73 | } |
| 66 | 74 | |
| 67 | 75 | // 2. 更新主表 |
| ... | ... | @@ -73,7 +81,7 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ |
| 73 | 81 | @Transactional(rollbackFor = Exception.class) |
| 74 | 82 | public void deleteProductionIssue(Long id) { |
| 75 | 83 | // 1. 校验存在 + 准备中状态 |
| 76 | - validateIssueExistsAndPrepare(id); | |
| 84 | + validateProductionIssueExistsAndPrepare(id); | |
| 77 | 85 | |
| 78 | 86 | // 2.1 级联删除明细 |
| 79 | 87 | issueDetailService.deleteProductionIssueDetailByIssueId(id); |
| ... | ... | @@ -95,21 +103,85 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ |
| 95 | 103 | |
| 96 | 104 | @Override |
| 97 | 105 | @Transactional(rollbackFor = Exception.class) |
| 106 | + public void submitProductionIssue(Long id) { | |
| 107 | + // 校验存在 + 草稿状态 | |
| 108 | + validateProductionIssueExistsAndPrepare(id); | |
| 109 | + // 校验至少有一条行 | |
| 110 | + List<MesWmProductionIssueLineDO> lines = issueLineService.getProductionIssueLineListByIssueId(id); | |
| 111 | + if (CollUtil.isEmpty(lines)) { | |
| 112 | + throw exception(WM_PRODUCTION_ISSUE_NO_LINE); | |
| 113 | + } | |
| 114 | + | |
| 115 | + // 提交(草稿 → 待拣货) | |
| 116 | + issueMapper.updateById(new MesWmProductionIssueDO() | |
| 117 | + .setId(id).setStatus(MesWmProductionIssueStatusEnum.APPROVING.getStatus())); | |
| 118 | + } | |
| 119 | + | |
| 120 | + @Override | |
| 121 | + @Transactional(rollbackFor = Exception.class) | |
| 122 | + public void stockProductionIssue(Long id) { | |
| 123 | + // 校验存在 | |
| 124 | + MesWmProductionIssueDO issue = validateProductionIssueExists(id); | |
| 125 | + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVING.getStatus(), issue.getStatus())) { | |
| 126 | + throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); | |
| 127 | + } | |
| 128 | + // 校验每行明细数量之和是否等于行领料数量 | |
| 129 | + List<MesWmProductionIssueLineDO> lines = issueLineService.getProductionIssueLineListByIssueId(id); | |
| 130 | + for (MesWmProductionIssueLineDO line : lines) { | |
| 131 | + List<MesWmProductionIssueDetailDO> details = issueDetailService.getProductionIssueDetailListByLineId(line.getId()); | |
| 132 | + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details, | |
| 133 | + MesWmProductionIssueDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO); | |
| 134 | + if (line.getQuantity() != null && totalDetailQty.compareTo(line.getQuantity()) != 0) { | |
| 135 | + throw exception(WM_PRODUCTION_ISSUE_DETAIL_QUANTITY_MISMATCH); | |
| 136 | + } | |
| 137 | + } | |
| 138 | + | |
| 139 | + // 执行拣货(待拣货 → 待执行领出) | |
| 140 | + issueMapper.updateById(new MesWmProductionIssueDO() | |
| 141 | + .setId(id).setStatus(MesWmProductionIssueStatusEnum.APPROVED.getStatus())); | |
| 142 | + } | |
| 143 | + | |
| 144 | + @Override | |
| 145 | + @Transactional(rollbackFor = Exception.class) | |
| 98 | 146 | public void finishProductionIssue(Long id) { |
| 99 | - // 1.1 校验存在 | |
| 100 | - MesWmProductionIssueDO issue = validateIssueExists(id); | |
| 101 | - // 1.2 校验状态:只有草稿才允许完成 | |
| 102 | - if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issue.getStatus())) { | |
| 147 | + // 校验存在 | |
| 148 | + MesWmProductionIssueDO issue = validateProductionIssueExists(id); | |
| 149 | + if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.APPROVED.getStatus(), issue.getStatus())) { | |
| 103 | 150 | throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); |
| 104 | 151 | } |
| 105 | 152 | |
| 106 | - // 2. 草稿 → 已完成 | |
| 107 | - // TODO @芋艿:库存扣减逻辑待完善(需要确定仓库ID的来源,可能需要在 line 或 detail 表中添加 warehouseId 字段) | |
| 153 | + // 遍历所有明细,更新库存台账(扣减库存) | |
| 154 | + // TODO @芋艿:【后续在弄】这里可能有点问题;缺少库存更新;后面在弄; | |
| 155 | + List<MesWmProductionIssueDetailDO> details = issueDetailService.getProductionIssueDetailListByIssueId(id); | |
| 156 | + for (MesWmProductionIssueDetailDO detail : details) { | |
| 157 | + // materialStockService.decreaseStock( | |
| 158 | + // detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(), | |
| 159 | + // detail.getBatchId(), detail.getQuantity(), issue.getWorkOrderId(), null, null); | |
| 160 | + } | |
| 161 | + | |
| 162 | + // 更新出库单状态 | |
| 108 | 163 | issueMapper.updateById(new MesWmProductionIssueDO() |
| 109 | 164 | .setId(id).setStatus(MesWmProductionIssueStatusEnum.FINISHED.getStatus())); |
| 110 | 165 | } |
| 111 | 166 | |
| 112 | - private MesWmProductionIssueDO validateIssueExists(Long id) { | |
| 167 | + @Override | |
| 168 | + @Transactional(rollbackFor = Exception.class) | |
| 169 | + public void cancelProductionIssue(Long id) { | |
| 170 | + // 校验存在 | |
| 171 | + MesWmProductionIssueDO issue = validateProductionIssueExists(id); | |
| 172 | + // 已完成和已取消不允许取消 | |
| 173 | + if (ObjectUtils.equalsAny(issue.getStatus(), | |
| 174 | + MesWmProductionIssueStatusEnum.FINISHED.getStatus(), | |
| 175 | + MesWmProductionIssueStatusEnum.CANCELED.getStatus())) { | |
| 176 | + throw exception(WM_PRODUCTION_ISSUE_CANCEL_NOT_ALLOWED); | |
| 177 | + } | |
| 178 | + // 取消 | |
| 179 | + issueMapper.updateById(new MesWmProductionIssueDO() | |
| 180 | + .setId(id).setStatus(MesWmProductionIssueStatusEnum.CANCELED.getStatus())); | |
| 181 | + } | |
| 182 | + | |
| 183 | + @Override | |
| 184 | + public MesWmProductionIssueDO validateProductionIssueExists(Long id) { | |
| 113 | 185 | MesWmProductionIssueDO issue = issueMapper.selectById(id); |
| 114 | 186 | if (issue == null) { |
| 115 | 187 | throw exception(WM_PRODUCTION_ISSUE_NOT_EXISTS); |
| ... | ... | @@ -120,8 +192,8 @@ public class MesWmProductionIssueServiceImpl implements MesWmProductionIssueServ |
| 120 | 192 | /** |
| 121 | 193 | * 校验领料出库单存在且为准备中状态 |
| 122 | 194 | */ |
| 123 | - private MesWmProductionIssueDO validateIssueExistsAndPrepare(Long id) { | |
| 124 | - MesWmProductionIssueDO issue = validateIssueExists(id); | |
| 195 | + private MesWmProductionIssueDO validateProductionIssueExistsAndPrepare(Long id) { | |
| 196 | + MesWmProductionIssueDO issue = validateProductionIssueExists(id); | |
| 125 | 197 | if (ObjUtil.notEqual(MesWmProductionIssueStatusEnum.PREPARE.getStatus(), issue.getStatus())) { |
| 126 | 198 | throw exception(WM_PRODUCTION_ISSUE_STATUS_INVALID); |
| 127 | 199 | } | ... | ... |