Commit 05ec61e6de5afc124e1b3827b2ce6de98c64c7f8

Authored by YunaiV
1 parent 97e55806

✨ feat(mes): 添加到货通知单精简列表接口及状态筛选功能

新增获取到货通知单的精简列表接口,支持按状态筛选。更新相关状态枚举和校验逻辑,优化采购入库单的审批和取消功能,确保系统在处理入库单时的状态管理更加清晰和高效。
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/MesWmArrivalNoticeController.java
@@ -121,6 +121,15 @@ public class MesWmArrivalNoticeController { @@ -121,6 +121,15 @@ public class MesWmArrivalNoticeController {
121 return success(true); 121 return success(true);
122 } 122 }
123 123
  124 + @GetMapping("/simple-list")
  125 + @Operation(summary = "获得到货通知单精简列表")
  126 + @Parameter(name = "status", description = "状态", example = "2")
  127 + public CommonResult<List<MesWmArrivalNoticeRespVO>> getArrivalNoticeSimpleList(
  128 + @RequestParam(value = "status", required = false) Integer status) {
  129 + List<MesWmArrivalNoticeDO> list = arrivalNoticeService.getArrivalNoticeListByStatus(status);
  130 + return success(buildRespVOList(list));
  131 + }
  132 +
124 // ==================== 拼接 VO ==================== 133 // ==================== 拼接 VO ====================
125 134
126 private List<MesWmArrivalNoticeRespVO> buildRespVOList(List<MesWmArrivalNoticeDO> list) { 135 private List<MesWmArrivalNoticeRespVO> buildRespVOList(List<MesWmArrivalNoticeDO> list) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptController.java
@@ -137,12 +137,13 @@ public class MesWmItemReceiptController { @@ -137,12 +137,13 @@ public class MesWmItemReceiptController {
137 return success(true); 137 return success(true);
138 } 138 }
139 139
140 - @PutMapping("/approve")  
141 - @Operation(summary = "审批采购入库单") 140 + // TODO @芋艿:【待定,不要删除】这个是合适的单词么?
  141 + @PutMapping("/shelving")
  142 + @Operation(summary = "执行上架")
142 @Parameter(name = "id", description = "编号", required = true) 143 @Parameter(name = "id", description = "编号", required = true)
143 @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')") 144 @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')")
144 - public CommonResult<Boolean> approveItemReceipt(@RequestParam("id") Long id) {  
145 - itemReceiptService.approveItemReceipt(id); 145 + public CommonResult<Boolean> shelvingItemReceipt(@RequestParam("id") Long id) {
  146 + itemReceiptService.shelvingItemReceipt(id);
146 return success(true); 147 return success(true);
147 } 148 }
148 149
@@ -155,6 +156,15 @@ public class MesWmItemReceiptController { @@ -155,6 +156,15 @@ public class MesWmItemReceiptController {
155 return success(true); 156 return success(true);
156 } 157 }
157 158
  159 + @PutMapping("/cancel")
  160 + @Operation(summary = "取消采购入库单")
  161 + @Parameter(name = "id", description = "编号", required = true)
  162 + @PreAuthorize("@ss.hasPermission('mes:wm-item-receipt:update')")
  163 + public CommonResult<Boolean> cancelItemReceipt(@RequestParam("id") Long id) {
  164 + itemReceiptService.cancelItemReceipt(id);
  165 + return success(true);
  166 + }
  167 +
158 // ==================== 拼接 VO ==================== 168 // ==================== 拼接 VO ====================
159 169
160 private List<MesWmItemReceiptRespVO> buildRespVOList(List<MesWmItemReceiptDO> list) { 170 private List<MesWmItemReceiptRespVO> buildRespVOList(List<MesWmItemReceiptDO> list) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
@@ -53,6 +53,7 @@ public class MesWmItemReceiptDO extends BaseDO { @@ -53,6 +53,7 @@ public class MesWmItemReceiptDO extends BaseDO {
53 * 关联 {@link MesWmArrivalNoticeDO#getId()} 53 * 关联 {@link MesWmArrivalNoticeDO#getId()}
54 */ 54 */
55 private Long noticeId; 55 private Long noticeId;
  56 + // TODO @AI:不用存储,它冗余自 noticeId 订单,可以需要的时候去读取!
56 /** 57 /**
57 * 采购订单编号 58 * 采购订单编号
58 */ 59 */
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -322,8 +322,8 @@ public interface ErrorCodeConstants { @@ -322,8 +322,8 @@ public interface ErrorCodeConstants {
322 ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在"); 322 ErrorCode WM_ARRIVAL_NOTICE_NOT_EXISTS = new ErrorCode(1_040_704_000, "到货通知单不存在");
323 ErrorCode WM_ARRIVAL_NOTICE_CODE_DUPLICATE = new ErrorCode(1_040_704_001, "到货通知单编码已存在"); 323 ErrorCode WM_ARRIVAL_NOTICE_CODE_DUPLICATE = new ErrorCode(1_040_704_001, "到货通知单编码已存在");
324 ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE = new ErrorCode(1_040_704_002, "只有草稿状态才允许此操作"); 324 ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE = new ErrorCode(1_040_704_002, "只有草稿状态才允许此操作");
325 - ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_SUBMITTED = new ErrorCode(1_040_704_003, "只有已提交状态才允许审批");  
326 - ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_APPROVED = new ErrorCode(1_040_704_004, "只有已审批状态才允许完成"); 325 + ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_QC = new ErrorCode(1_040_704_003, "只有待质检状态才允许审批");
  326 + ErrorCode WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_RECEIPT = new ErrorCode(1_040_704_004, "只有待入库状态才允许完成");
327 ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过"); 327 ErrorCode WM_ARRIVAL_NOTICE_IQC_PENDING = new ErrorCode(1_040_704_005, "存在待检验行,无法审批通过");
328 ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目"); 328 ErrorCode WM_ARRIVAL_NOTICE_NO_LINE = new ErrorCode(1_040_704_006, "至少需要一条行项目");
329 ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在"); 329 ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在");
@@ -331,10 +331,11 @@ public interface ErrorCodeConstants { @@ -331,10 +331,11 @@ public interface ErrorCodeConstants {
331 // ========== MES 仓库管理-采购入库单(1-040-705-000) ========== 331 // ========== MES 仓库管理-采购入库单(1-040-705-000) ==========
332 ErrorCode WM_ITEM_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_705_000, "采购入库单不存在"); 332 ErrorCode WM_ITEM_RECEIPT_NOT_EXISTS = new ErrorCode(1_040_705_000, "采购入库单不存在");
333 ErrorCode WM_ITEM_RECEIPT_CODE_DUPLICATE = new ErrorCode(1_040_705_001, "采购入库单编码已存在"); 333 ErrorCode WM_ITEM_RECEIPT_CODE_DUPLICATE = new ErrorCode(1_040_705_001, "采购入库单编码已存在");
334 - ErrorCode WM_ITEM_RECEIPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_705_002, "只有草稿状态才允许此操作"); 334 + ErrorCode WM_ITEM_RECEIPT_STATUS_NOT_PREPARE = new ErrorCode(1_040_705_002, "只有草稿或待上架状态才允许此操作");
335 ErrorCode WM_ITEM_RECEIPT_NO_LINE = new ErrorCode(1_040_705_003, "至少需要一条行项目"); 335 ErrorCode WM_ITEM_RECEIPT_NO_LINE = new ErrorCode(1_040_705_003, "至少需要一条行项目");
336 ErrorCode WM_ITEM_RECEIPT_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_705_004, "明细上架总数与行入库数量不匹配"); 336 ErrorCode WM_ITEM_RECEIPT_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_705_004, "明细上架总数与行入库数量不匹配");
337 ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "入库单状态不正确"); 337 ErrorCode WM_ITEM_RECEIPT_STATUS_ERROR = new ErrorCode(1_040_705_005, "入库单状态不正确");
  338 + ErrorCode WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED = new ErrorCode(1_040_705_006, "已完成或已取消的入库单不允许取消");
338 ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "采购入库单行不存在"); 339 ErrorCode WM_ITEM_RECEIPT_LINE_NOT_EXISTS = new ErrorCode(1_040_705_100, "采购入库单行不存在");
339 ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在"); 340 ErrorCode WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS = new ErrorCode(1_040_705_200, "采购入库明细不存在");
340 341
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmArrivalNoticeStatusEnum.java
@@ -16,8 +16,8 @@ import java.util.Arrays; @@ -16,8 +16,8 @@ import java.util.Arrays;
16 public enum MesWmArrivalNoticeStatusEnum implements ArrayValuable<Integer> { 16 public enum MesWmArrivalNoticeStatusEnum implements ArrayValuable<Integer> {
17 17
18 PREPARE(0, "草稿"), 18 PREPARE(0, "草稿"),
19 - SUBMITTED(1, "已提交"),  
20 - APPROVED(2, "已审批"), 19 + PENDING_QC(1, "待质检"),
  20 + PENDING_RECEIPT(2, "待入库"),
21 FINISHED(3, "已完成"); 21 FINISHED(3, "已完成");
22 22
23 public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmArrivalNoticeStatusEnum::getStatus).toArray(Integer[]::new); 23 public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmArrivalNoticeStatusEnum::getStatus).toArray(Integer[]::new);
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemReceiptStatusEnum.java
@@ -16,9 +16,10 @@ import java.util.Arrays; @@ -16,9 +16,10 @@ import java.util.Arrays;
16 public enum MesWmItemReceiptStatusEnum implements ArrayValuable<Integer> { 16 public enum MesWmItemReceiptStatusEnum implements ArrayValuable<Integer> {
17 17
18 PREPARE(0, "草稿"), 18 PREPARE(0, "草稿"),
19 - SUBMITTED(1, "已提交"),  
20 - APPROVED(2, "已审批"),  
21 - FINISHED(3, "已完成"); 19 + APPROVING(1, "待上架"),
  20 + APPROVED(2, "待入库"),
  21 + FINISHED(3, "已完成"),
  22 + CANCELED(4, "已取消");
22 23
23 public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemReceiptStatusEnum::getStatus).toArray(Integer[]::new); 24 public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemReceiptStatusEnum::getStatus).toArray(Integer[]::new);
24 25
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java
@@ -56,21 +56,21 @@ public interface MesWmArrivalNoticeService { @@ -56,21 +56,21 @@ public interface MesWmArrivalNoticeService {
56 PageResult<MesWmArrivalNoticeDO> getArrivalNoticePage(MesWmArrivalNoticePageReqVO pageReqVO); 56 PageResult<MesWmArrivalNoticeDO> getArrivalNoticePage(MesWmArrivalNoticePageReqVO pageReqVO);
57 57
58 /** 58 /**
59 - * 提交到货通知单(草稿 → 已提交) 59 + * 提交到货通知单(草稿 → 待质检/待入库)
60 * 60 *
61 * @param id 编号 61 * @param id 编号
62 */ 62 */
63 void submitArrivalNotice(Long id); 63 void submitArrivalNotice(Long id);
64 64
65 /** 65 /**
66 - * 审批到货通知单(已提交 → 已审批) 66 + * 审批到货通知单(待质检 → 待入库)
67 * 67 *
68 * @param id 编号 68 * @param id 编号
69 */ 69 */
70 void approveArrivalNotice(Long id); 70 void approveArrivalNotice(Long id);
71 71
72 /** 72 /**
73 - * 完成到货通知单(已审批 → 已完成),内部调用 73 + * 完成到货通知单(待入库 → 已完成),内部调用
74 * 74 *
75 * @param id 编号 75 * @param id 编号
76 */ 76 */
@@ -88,4 +88,12 @@ public interface MesWmArrivalNoticeService { @@ -88,4 +88,12 @@ public interface MesWmArrivalNoticeService {
88 return convertMap(getArrivalNoticeList(ids), MesWmArrivalNoticeDO::getId); 88 return convertMap(getArrivalNoticeList(ids), MesWmArrivalNoticeDO::getId);
89 } 89 }
90 90
  91 + /**
  92 + * 按状态获得到货通知单列表
  93 + *
  94 + * @param status 状态
  95 + * @return 到货通知单列表
  96 + */
  97 + List<MesWmArrivalNoticeDO> getArrivalNoticeListByStatus(Integer status);
  98 +
91 } 99 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
@@ -96,13 +96,13 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -96,13 +96,13 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
96 // 检查所有行的 iqcCheckFlag:如果没有需要检验的行,则直接审批通过 96 // 检查所有行的 iqcCheckFlag:如果没有需要检验的行,则直接审批通过
97 boolean needCheck = CollectionUtils.anyMatch(lines, line -> Boolean.TRUE.equals(line.getIqcCheckFlag())); 97 boolean needCheck = CollectionUtils.anyMatch(lines, line -> Boolean.TRUE.equals(line.getIqcCheckFlag()));
98 if (!needCheck) { 98 if (!needCheck) {
99 - // 不需要检验,直接审批通过 99 + // 不需要检验,直接进入待入库
100 arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() 100 arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
101 - .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.APPROVED.getStatus())); 101 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus()));
102 } else { 102 } else {
103 - // 需要检验,提交待审批 103 + // 需要检验,进入待质检
104 arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() 104 arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
105 - .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.SUBMITTED.getStatus())); 105 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus()));
106 } 106 }
107 } 107 }
108 108
@@ -111,9 +111,9 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -111,9 +111,9 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
111 public void approveArrivalNotice(Long id) { 111 public void approveArrivalNotice(Long id) {
112 // 校验存在 112 // 校验存在
113 MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id); 113 MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);
114 - // 校验状态:只有已提交才允许审批  
115 - if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.SUBMITTED.getStatus(), notice.getStatus())) {  
116 - throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_SUBMITTED); 114 + // 校验状态:只有待质检才允许审批
  115 + if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus(), notice.getStatus())) {
  116 + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_QC);
117 } 117 }
118 118
119 // 校验所有 iqcCheckFlag=true 的行必须 iqcId 不为空 119 // 校验所有 iqcCheckFlag=true 的行必须 iqcId 不为空
@@ -125,16 +125,16 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -125,16 +125,16 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
125 } 125 }
126 // 审批通过 126 // 审批通过
127 arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() 127 arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
128 - .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.APPROVED.getStatus())); 128 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus()));
129 } 129 }
130 130
131 @Override 131 @Override
132 public void finishArrivalNotice(Long id) { 132 public void finishArrivalNotice(Long id) {
133 // 校验存在 133 // 校验存在
134 MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id); 134 MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);
135 - // 校验状态:只有已审批才允许完成  
136 - if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.APPROVED.getStatus(), notice.getStatus())) {  
137 - throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_APPROVED); 135 + // 校验状态:只有待入库才允许完成
  136 + if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus(), notice.getStatus())) {
  137 + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_RECEIPT);
138 } 138 }
139 139
140 // 完成 140 // 完成
@@ -150,6 +150,15 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -150,6 +150,15 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
150 return arrivalNoticeMapper.selectByIds(ids); 150 return arrivalNoticeMapper.selectByIds(ids);
151 } 151 }
152 152
  153 + @Override
  154 + public List<MesWmArrivalNoticeDO> getArrivalNoticeListByStatus(Integer status) {
  155 + // TODO @AI:通过 selectListByStatus 方法实现,更通用;
  156 + if (status == null) {
  157 + return arrivalNoticeMapper.selectList();
  158 + }
  159 + return arrivalNoticeMapper.selectList(MesWmArrivalNoticeDO::getStatus, status);
  160 + }
  161 +
153 private MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) { 162 private MesWmArrivalNoticeDO validateArrivalNoticeExists(Long id) {
154 MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectById(id); 163 MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectById(id);
155 if (notice == null) { 164 if (notice == null) {
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.service.wm.itemreceipt; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.service.wm.itemreceipt;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
  5 +import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
5 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailPageReqVO; 6 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailPageReqVO;
6 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailSaveReqVO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO; 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
@@ -36,7 +37,7 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -36,7 +37,7 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
36 @Override 37 @Override
37 public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) { 38 public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) {
38 // 校验父单据存在且为草稿状态 39 // 校验父单据存在且为草稿状态
39 - validateReceiptStatusDraft(createReqVO.getReceiptId()); 40 + validateReceiptStatusForDetailEdit(createReqVO.getReceiptId());
40 41
41 MesWmItemReceiptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmItemReceiptDetailDO.class); 42 MesWmItemReceiptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmItemReceiptDetailDO.class);
42 itemReceiptDetailMapper.insert(detail); 43 itemReceiptDetailMapper.insert(detail);
@@ -48,7 +49,7 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -48,7 +49,7 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
48 // 校验存在 49 // 校验存在
49 MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId()); 50 MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId());
50 // 校验父单据存在且为草稿状态 51 // 校验父单据存在且为草稿状态
51 - validateReceiptStatusDraft(detail.getReceiptId()); 52 + validateReceiptStatusForDetailEdit(detail.getReceiptId());
52 53
53 // 更新 54 // 更新
54 MesWmItemReceiptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDetailDO.class); 55 MesWmItemReceiptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDetailDO.class);
@@ -101,15 +102,18 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -101,15 +102,18 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
101 return detail; 102 return detail;
102 } 103 }
103 104
  105 + // TODO @AI:在 itemReceiptService 里,封装一个这个方法;最好不要是 fordetail,而不是 prepare + approving 状态;
104 /** 106 /**
105 - * 校验父采购入库单存在且为草稿状态 107 + * 校验父采购入库单存在且允许编辑明细(草稿或待上架状态)
106 */ 108 */
107 - private void validateReceiptStatusDraft(Long receiptId) { 109 + private void validateReceiptStatusForDetailEdit(Long receiptId) {
108 MesWmItemReceiptDO receipt = itemReceiptService.getItemReceipt(receiptId); 110 MesWmItemReceiptDO receipt = itemReceiptService.getItemReceipt(receiptId);
109 if (receipt == null) { 111 if (receipt == null) {
110 throw exception(WM_ITEM_RECEIPT_NOT_EXISTS); 112 throw exception(WM_ITEM_RECEIPT_NOT_EXISTS);
111 } 113 }
112 - if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())) { 114 + // TODO @AI:在 ObjectUtils 里,封装一个 notEquals 方法,简化代码;
  115 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())
  116 + && ObjUtil.notEqual(MesWmItemReceiptStatusEnum.APPROVING.getStatus(), receipt.getStatus())) {
113 throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE); 117 throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);
114 } 118 }
115 } 119 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java
@@ -50,24 +50,31 @@ public interface MesWmItemReceiptService { @@ -50,24 +50,31 @@ public interface MesWmItemReceiptService {
50 PageResult<MesWmItemReceiptDO> getItemReceiptPage(MesWmItemReceiptPageReqVO pageReqVO); 50 PageResult<MesWmItemReceiptDO> getItemReceiptPage(MesWmItemReceiptPageReqVO pageReqVO);
51 51
52 /** 52 /**
53 - * 提交采购入库单(草稿 → 已提交) 53 + * 提交采购入库单(草稿 → 待上架)
54 * 54 *
55 * @param id 编号 55 * @param id 编号
56 */ 56 */
57 void submitItemReceipt(Long id); 57 void submitItemReceipt(Long id);
58 58
59 /** 59 /**
60 - * 审批采购入库单(已提交 → 已审批) 60 + * 执行上架(待上架 → 待入库)
61 * 61 *
62 * @param id 编号 62 * @param id 编号
63 */ 63 */
64 - void approveItemReceipt(Long id); 64 + void shelvingItemReceipt(Long id);
65 65
66 /** 66 /**
67 - * 执行入库(已审批 → 已完成),更新库存台账 67 + * 执行入库(待入库 → 已完成),更新库存台账
68 * 68 *
69 * @param id 编号 69 * @param id 编号
70 */ 70 */
71 void executeItemReceipt(Long id); 71 void executeItemReceipt(Long id);
72 72
  73 + /**
  74 + * 取消采购入库单(任意非已完成/已取消状态 → 已取消)
  75 + *
  76 + * @param id 编号
  77 + */
  78 + void cancelItemReceipt(Long id);
  79 +
73 } 80 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
@@ -107,17 +107,17 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -107,17 +107,17 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
107 throw exception(WM_ITEM_RECEIPT_NO_LINE); 107 throw exception(WM_ITEM_RECEIPT_NO_LINE);
108 } 108 }
109 109
110 - // 提交 110 + // 提交(草稿 → 待上架)
111 itemReceiptMapper.updateById(new MesWmItemReceiptDO() 111 itemReceiptMapper.updateById(new MesWmItemReceiptDO()
112 - .setId(id).setStatus(MesWmItemReceiptStatusEnum.SUBMITTED.getStatus())); 112 + .setId(id).setStatus(MesWmItemReceiptStatusEnum.APPROVING.getStatus()));
113 } 113 }
114 114
115 @Override 115 @Override
116 @Transactional(rollbackFor = Exception.class) 116 @Transactional(rollbackFor = Exception.class)
117 - public void approveItemReceipt(Long id) { 117 + public void shelvingItemReceipt(Long id) {
118 // 校验存在 118 // 校验存在
119 MesWmItemReceiptDO receipt = validateItemReceiptExists(id); 119 MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
120 - if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.SUBMITTED.getStatus(), receipt.getStatus())) { 120 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.APPROVING.getStatus(), receipt.getStatus())) {
121 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR); 121 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR);
122 } 122 }
123 // 校验每行的 SUM(detail.quantity) = line.receivedQuantity 123 // 校验每行的 SUM(detail.quantity) = line.receivedQuantity
@@ -131,7 +131,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -131,7 +131,7 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
131 } 131 }
132 } 132 }
133 133
134 - // 审批 134 + // 执行上架(待上架 → 待入库)
135 itemReceiptMapper.updateById(new MesWmItemReceiptDO() 135 itemReceiptMapper.updateById(new MesWmItemReceiptDO()
136 .setId(id).setStatus(MesWmItemReceiptStatusEnum.APPROVED.getStatus())); 136 .setId(id).setStatus(MesWmItemReceiptStatusEnum.APPROVED.getStatus()));
137 } 137 }
@@ -162,6 +162,23 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -162,6 +162,23 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
162 } 162 }
163 } 163 }
164 164
  165 + @Override
  166 + @Transactional(rollbackFor = Exception.class)
  167 + public void cancelItemReceipt(Long id) {
  168 + // 校验存在
  169 + MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
  170 + // 已完成和已取消不允许取消
  171 + // TODO @AI:在 ObjectUtils 里,有个 equalsAny;
  172 + // TODO @芋艿:【待确定】是不是就这 2 个状态了;
  173 + if (ObjUtil.equal(MesWmItemReceiptStatusEnum.FINISHED.getStatus(), receipt.getStatus())
  174 + || ObjUtil.equal(MesWmItemReceiptStatusEnum.CANCELED.getStatus(), receipt.getStatus())) {
  175 + throw exception(WM_ITEM_RECEIPT_CANCEL_NOT_ALLOWED);
  176 + }
  177 + // 取消
  178 + itemReceiptMapper.updateById(new MesWmItemReceiptDO()
  179 + .setId(id).setStatus(MesWmItemReceiptStatusEnum.CANCELED.getStatus()));
  180 + }
  181 +
165 private MesWmItemReceiptDO validateItemReceiptExists(Long id) { 182 private MesWmItemReceiptDO validateItemReceiptExists(Long id) {
166 MesWmItemReceiptDO receipt = itemReceiptMapper.selectById(id); 183 MesWmItemReceiptDO receipt = itemReceiptMapper.selectById(id);
167 if (receipt == null) { 184 if (receipt == null) {