Commit a5c49881aab071a35e56375132af637008ff777d

Authored by YunaiV
1 parent 7a593977

✨ feat(mes): 添加到货通知单和入库单的状态枚举及相关校验

新增 MES 到货通知单和入库单的状态枚举类,提供更清晰的状态管理。
同时在相关服务中添加了对父单据状态的校验,确保只有在草稿状态下才能进行修改和删除操作。

此变更提升了代码的可读性和维护性,减少了硬编码的状态值使用。
Showing 23 changed files with 370 additions and 165 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/MesWmArrivalNoticeLineController.java
@@ -104,20 +104,16 @@ public class MesWmArrivalNoticeLineController { @@ -104,20 +104,16 @@ public class MesWmArrivalNoticeLineController {
104 // 1. 获得关联数据 104 // 1. 获得关联数据
105 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap( 105 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
106 convertSet(list, MesWmArrivalNoticeLineDO::getItemId)); 106 convertSet(list, MesWmArrivalNoticeLineDO::getItemId));
  107 + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
  108 + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
107 Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap( 109 Map<Long, MesQcIqcDO> iqcMap = iqcService.getIqcMap(
108 convertSet(list, MesWmArrivalNoticeLineDO::getIqcId)); 110 convertSet(list, MesWmArrivalNoticeLineDO::getIqcId));
109 // 2. 构建结果 111 // 2. 构建结果
110 return BeanUtils.toBean(list, MesWmArrivalNoticeLineRespVO.class, vo -> { 112 return BeanUtils.toBean(list, MesWmArrivalNoticeLineRespVO.class, vo -> {
111 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { 113 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
112 vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); 114 vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
113 - // 查询物料的计量单位名称  
114 - // TODO @AI:也批量查询,避免逐个;  
115 - if (item.getUnitMeasureId() != null) {  
116 - MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasure(item.getUnitMeasureId());  
117 - if (unitMeasure != null) {  
118 - vo.setUnitMeasureName(unitMeasure.getName());  
119 - }  
120 - } 115 + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
  116 + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
121 }); 117 });
122 MapUtils.findAndThen(iqcMap, vo.getIqcId(), iqc -> vo.setIqcCode(iqc.getCode())); 118 MapUtils.findAndThen(iqcMap, vo.getIqcId(), iqc -> vo.setIqcCode(iqc.getCode()));
123 }); 119 });
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/vo/line/MesWmArrivalNoticeLinePageReqVO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.NotNull;
5 import lombok.Data; 6 import lombok.Data;
6 import lombok.EqualsAndHashCode; 7 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 8 import lombok.ToString;
@@ -13,6 +14,7 @@ import lombok.ToString; @@ -13,6 +14,7 @@ import lombok.ToString;
13 public class MesWmArrivalNoticeLinePageReqVO extends PageParam { 14 public class MesWmArrivalNoticeLinePageReqVO extends PageParam {
14 15
15 @Schema(description = "到货通知单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 16 @Schema(description = "到货通知单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "到货通知单编号不能为空")
16 private Long noticeId; 18 private Long noticeId;
17 19
18 } 20 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/arrivalnotice/vo/line/MesWmArrivalNoticeLineSaveReqVO.java
@@ -21,7 +21,8 @@ public class MesWmArrivalNoticeLineSaveReqVO { @@ -21,7 +21,8 @@ public class MesWmArrivalNoticeLineSaveReqVO {
21 @NotNull(message = "物料编号不能为空") 21 @NotNull(message = "物料编号不能为空")
22 private Long itemId; 22 private Long itemId;
23 23
24 - @Schema(description = "到货数量", example = "500.00") 24 + @Schema(description = "到货数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "500.00")
  25 + @NotNull(message = "到货数量不能为空")
25 private BigDecimal arrivalQuantity; 26 private BigDecimal arrivalQuantity;
26 27
27 @Schema(description = "合格数量", example = "500.00") 28 @Schema(description = "合格数量", example = "500.00")
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptDetailController.java
@@ -114,6 +114,8 @@ public class MesWmItemReceiptDetailController { @@ -114,6 +114,8 @@ public class MesWmItemReceiptDetailController {
114 // 1. 获得关联数据 114 // 1. 获得关联数据
115 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap( 115 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
116 convertSet(list, MesWmItemReceiptDetailDO::getItemId)); 116 convertSet(list, MesWmItemReceiptDetailDO::getItemId));
  117 + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
  118 + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
117 Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( 119 Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
118 convertSet(list, MesWmItemReceiptDetailDO::getWarehouseId)); 120 convertSet(list, MesWmItemReceiptDetailDO::getWarehouseId));
119 Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap( 121 Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
@@ -124,13 +126,8 @@ public class MesWmItemReceiptDetailController { @@ -124,13 +126,8 @@ public class MesWmItemReceiptDetailController {
124 return BeanUtils.toBean(list, MesWmItemReceiptDetailRespVO.class, vo -> { 126 return BeanUtils.toBean(list, MesWmItemReceiptDetailRespVO.class, vo -> {
125 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { 127 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
126 vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); 128 vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
127 - // TODO @AI:批量查询,避免 N+1 查询  
128 - if (item.getUnitMeasureId() != null) {  
129 - MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasure(item.getUnitMeasureId());  
130 - if (unitMeasure != null) {  
131 - vo.setUnitMeasureName(unitMeasure.getName());  
132 - }  
133 - } 129 + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
  130 + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
134 }); 131 });
135 MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), 132 MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(),
136 warehouse -> vo.setWarehouseName(warehouse.getName())); 133 warehouse -> vo.setWarehouseName(warehouse.getName()));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/MesWmItemReceiptLineController.java
@@ -119,6 +119,8 @@ public class MesWmItemReceiptLineController { @@ -119,6 +119,8 @@ public class MesWmItemReceiptLineController {
119 // 1. 获得关联数据 119 // 1. 获得关联数据
120 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap( 120 Map<Long, MesMdItemDO> itemMap = itemService.getItemMap(
121 convertSet(list, MesWmItemReceiptLineDO::getItemId)); 121 convertSet(list, MesWmItemReceiptLineDO::getItemId));
  122 + Map<Long, MesMdUnitMeasureDO> unitMeasureMap = unitMeasureService.getUnitMeasureMap(
  123 + convertSet(itemMap.values(), MesMdItemDO::getUnitMeasureId));
122 Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap( 124 Map<Long, MesWmWarehouseDO> warehouseMap = warehouseService.getWarehouseMap(
123 convertSet(list, MesWmItemReceiptLineDO::getWarehouseId)); 125 convertSet(list, MesWmItemReceiptLineDO::getWarehouseId));
124 Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap( 126 Map<Long, MesWmWarehouseLocationDO> locationMap = locationService.getWarehouseLocationMap(
@@ -131,13 +133,8 @@ public class MesWmItemReceiptLineController { @@ -131,13 +133,8 @@ public class MesWmItemReceiptLineController {
131 return BeanUtils.toBean(list, MesWmItemReceiptLineRespVO.class, vo -> { 133 return BeanUtils.toBean(list, MesWmItemReceiptLineRespVO.class, vo -> {
132 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> { 134 MapUtils.findAndThen(itemMap, vo.getItemId(), item -> {
133 vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification()); 135 vo.setItemCode(item.getCode()).setItemName(item.getName()).setSpecification(item.getSpecification());
134 - // TODO @AI:批量查询,避免 N+1 查询  
135 - if (item.getUnitMeasureId() != null) {  
136 - MesMdUnitMeasureDO unitMeasure = unitMeasureService.getUnitMeasure(item.getUnitMeasureId());  
137 - if (unitMeasure != null) {  
138 - vo.setUnitMeasureName(unitMeasure.getName());  
139 - }  
140 - } 136 + MapUtils.findAndThen(unitMeasureMap, item.getUnitMeasureId(),
  137 + unitMeasure -> vo.setUnitMeasureName(unitMeasure.getName()));
141 }); 138 });
142 MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(), 139 MapUtils.findAndThen(warehouseMap, vo.getWarehouseId(),
143 warehouse -> vo.setWarehouseName(warehouse.getName())); 140 warehouse -> vo.setWarehouseName(warehouse.getName()));
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailPageReqVO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.detail;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.NotNull;
5 import lombok.Data; 6 import lombok.Data;
6 import lombok.EqualsAndHashCode; 7 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 8 import lombok.ToString;
@@ -12,10 +13,12 @@ import lombok.ToString; @@ -12,10 +13,12 @@ import lombok.ToString;
12 @ToString(callSuper = true) 13 @ToString(callSuper = true)
13 public class MesWmItemReceiptDetailPageReqVO extends PageParam { 14 public class MesWmItemReceiptDetailPageReqVO extends PageParam {
14 15
15 - @Schema(description = "入库单编号", example = "1") 16 + @Schema(description = "入库单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "入库单编号不能为空")
16 private Long receiptId; 18 private Long receiptId;
17 19
18 - @Schema(description = "入库单行编号", example = "1") 20 + @Schema(description = "入库单行编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  21 + @NotNull(message = "入库单行编号不能为空")
19 private Long lineId; 22 private Long lineId;
20 23
21 } 24 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/detail/MesWmItemReceiptDetailSaveReqVO.java
@@ -25,7 +25,8 @@ public class MesWmItemReceiptDetailSaveReqVO { @@ -25,7 +25,8 @@ public class MesWmItemReceiptDetailSaveReqVO {
25 @NotNull(message = "物料编号不能为空") 25 @NotNull(message = "物料编号不能为空")
26 private Long itemId; 26 private Long itemId;
27 27
28 - @Schema(description = "上架数量", example = "300.00") 28 + @Schema(description = "上架数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "300.00")
  29 + @NotNull(message = "上架数量不能为空")
29 private BigDecimal quantity; 30 private BigDecimal quantity;
30 31
31 @Schema(description = "批次编号", example = "1") 32 @Schema(description = "批次编号", example = "1")
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLinePageReqVO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
  5 +import jakarta.validation.constraints.NotNull;
5 import lombok.Data; 6 import lombok.Data;
6 import lombok.EqualsAndHashCode; 7 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 8 import lombok.ToString;
@@ -13,6 +14,7 @@ import lombok.ToString; @@ -13,6 +14,7 @@ import lombok.ToString;
13 public class MesWmItemReceiptLinePageReqVO extends PageParam { 14 public class MesWmItemReceiptLinePageReqVO extends PageParam {
14 15
15 @Schema(description = "入库单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 16 @Schema(description = "入库单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + @NotNull(message = "入库单编号不能为空")
16 private Long receiptId; 18 private Long receiptId;
17 19
18 } 20 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/itemreceipt/vo/line/MesWmItemReceiptLineSaveReqVO.java
@@ -25,7 +25,8 @@ public class MesWmItemReceiptLineSaveReqVO { @@ -25,7 +25,8 @@ public class MesWmItemReceiptLineSaveReqVO {
25 @NotNull(message = "物料编号不能为空") 25 @NotNull(message = "物料编号不能为空")
26 private Long itemId; 26 private Long itemId;
27 27
28 - @Schema(description = "入库数量", example = "500.00") 28 + @Schema(description = "入库数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "500.00")
  29 + @NotNull(message = "入库数量不能为空")
29 private BigDecimal receivedQuantity; 30 private BigDecimal receivedQuantity;
30 31
31 @Schema(description = "批次编号", example = "1") 32 @Schema(description = "批次编号", example = "1")
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/arrivalnotice/MesWmArrivalNoticeDO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO; 4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO;
  5 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum;
5 import com.baomidou.mybatisplus.annotation.KeySequence; 6 import com.baomidou.mybatisplus.annotation.KeySequence;
6 import com.baomidou.mybatisplus.annotation.TableId; 7 import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 8 import com.baomidou.mybatisplus.annotation.TableName;
@@ -57,12 +58,10 @@ public class MesWmArrivalNoticeDO extends BaseDO { @@ -57,12 +58,10 @@ public class MesWmArrivalNoticeDO extends BaseDO {
57 * 联系电话 58 * 联系电话
58 */ 59 */
59 private String contactTelephone; 60 private String contactTelephone;
60 - // TODO @AI:枚举类;需要 @关联  
61 - // TODO @AI:字典类;需要 @关联  
62 /** 61 /**
63 * 状态 62 * 状态
64 * 63 *
65 - * 0=草稿 1=已提交 2=已审批 3=已完成 64 + * 枚举 {@link MesWmArrivalNoticeStatusEnum}
66 */ 65 */
67 private Integer status; 66 private Integer status;
68 /** 67 /**
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/itemreceipt/MesWmItemReceiptDO.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt;
2 2
3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO; 4 import cn.iocoder.yudao.module.mes.dal.dataobject.md.vendor.MesMdVendorDO;
  5 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
5 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO; 6 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO;
6 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO; 7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseAreaDO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO; 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.warehouse.MesWmWarehouseDO;
@@ -84,12 +85,10 @@ public class MesWmItemReceiptDO extends BaseDO { @@ -84,12 +85,10 @@ public class MesWmItemReceiptDO extends BaseDO {
84 * 入库日期 85 * 入库日期
85 */ 86 */
86 private LocalDateTime receiptDate; 87 private LocalDateTime receiptDate;
87 - // TODO @AI:枚举类;需要 @关联  
88 - // TODO @AI:字典类;需要 @关联  
89 /** 88 /**
90 * 状态 89 * 状态
91 * 90 *
92 - * 0=草稿 1=已提交 2=已审批 3=已完成 91 + * 枚举 {@link MesWmItemReceiptStatusEnum}
93 */ 92 */
94 private Integer status; 93 private Integer status;
95 /** 94 /**
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmArrivalNoticeStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.wm;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 到货通知单状态枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesWmArrivalNoticeStatusEnum implements ArrayValuable<Integer> {
  17 +
  18 + PREPARE(0, "草稿"),
  19 + SUBMITTED(1, "已提交"),
  20 + APPROVED(2, "已审批"),
  21 + FINISHED(3, "已完成");
  22 +
  23 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmArrivalNoticeStatusEnum::getStatus).toArray(Integer[]::new);
  24 +
  25 + /**
  26 + * 状态值
  27 + */
  28 + private final Integer status;
  29 + /**
  30 + * 状态名
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public Integer[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmItemReceiptStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.mes.enums.wm;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.ArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * MES 采购入库单状态枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum MesWmItemReceiptStatusEnum implements ArrayValuable<Integer> {
  17 +
  18 + PREPARE(0, "草稿"),
  19 + SUBMITTED(1, "已提交"),
  20 + APPROVED(2, "已审批"),
  21 + FINISHED(3, "已完成");
  22 +
  23 + public static final Integer[] ARRAYS = Arrays.stream(values()).map(MesWmItemReceiptStatusEnum::getStatus).toArray(Integer[]::new);
  24 +
  25 + /**
  26 + * 状态值
  27 + */
  28 + private final Integer status;
  29 + /**
  30 + * 状态名
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public Integer[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineService.java
@@ -51,7 +51,6 @@ public interface MesWmArrivalNoticeLineService { @@ -51,7 +51,6 @@ public interface MesWmArrivalNoticeLineService {
51 */ 51 */
52 PageResult<MesWmArrivalNoticeLineDO> getArrivalNoticeLinePage(MesWmArrivalNoticeLinePageReqVO pageReqVO); 52 PageResult<MesWmArrivalNoticeLineDO> getArrivalNoticeLinePage(MesWmArrivalNoticeLinePageReqVO pageReqVO);
53 53
54 - // TODO @AI:不用的接口,就删除掉;  
55 /** 54 /**
56 * 按通知单编号获得行列表 55 * 按通知单编号获得行列表
57 * 56 *
@@ -60,4 +59,11 @@ public interface MesWmArrivalNoticeLineService { @@ -60,4 +59,11 @@ public interface MesWmArrivalNoticeLineService {
60 */ 59 */
61 List<MesWmArrivalNoticeLineDO> getArrivalNoticeLineListByNoticeId(Long noticeId); 60 List<MesWmArrivalNoticeLineDO> getArrivalNoticeLineListByNoticeId(Long noticeId);
62 61
  62 + /**
  63 + * 按通知单编号批量删除行
  64 + *
  65 + * @param noticeId 通知单编号
  66 + */
  67 + void deleteArrivalNoticeLineByNoticeId(Long noticeId);
  68 +
63 } 69 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineServiceImpl.java
1 package cn.iocoder.yudao.module.mes.service.wm.arrivalnotice; 1 package cn.iocoder.yudao.module.mes.service.wm.arrivalnotice;
2 2
  3 +import cn.hutool.core.util.BooleanUtil;
  4 +import cn.hutool.core.util.ObjUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 6 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLinePageReqVO; 7 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLinePageReqVO;
6 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLineSaveReqVO; 8 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.line.MesWmArrivalNoticeLineSaveReqVO;
  9 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; 10 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO;
8 import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeLineMapper; 11 import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeLineMapper;
  12 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum;
9 import jakarta.annotation.Resource; 13 import jakarta.annotation.Resource;
  14 +import org.springframework.context.annotation.Lazy;
10 import org.springframework.stereotype.Service; 15 import org.springframework.stereotype.Service;
11 import org.springframework.validation.annotation.Validated; 16 import org.springframework.validation.annotation.Validated;
12 17
13 import java.util.List; 18 import java.util.List;
14 19
15 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16 -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS; 21 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
17 22
18 /** 23 /**
19 * MES 到货通知单行 Service 实现类 24 * MES 到货通知单行 Service 实现类
@@ -25,15 +30,19 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine @@ -25,15 +30,19 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine
25 @Resource 30 @Resource
26 private MesWmArrivalNoticeLineMapper arrivalNoticeLineMapper; 31 private MesWmArrivalNoticeLineMapper arrivalNoticeLineMapper;
27 32
  33 + @Resource
  34 + @Lazy
  35 + private MesWmArrivalNoticeService arrivalNoticeService;
  36 +
28 @Override 37 @Override
29 public Long createArrivalNoticeLine(MesWmArrivalNoticeLineSaveReqVO createReqVO) { 38 public Long createArrivalNoticeLine(MesWmArrivalNoticeLineSaveReqVO createReqVO) {
30 - // TODO @AI:关联表的校验; 39 + // 校验父单据存在且为草稿状态
  40 + validateNoticeStatusDraft(createReqVO.getNoticeId());
31 41
32 // 插入 42 // 插入
33 MesWmArrivalNoticeLineDO line = BeanUtils.toBean(createReqVO, MesWmArrivalNoticeLineDO.class); 43 MesWmArrivalNoticeLineDO line = BeanUtils.toBean(createReqVO, MesWmArrivalNoticeLineDO.class);
34 // 如果不需要检验,则合格品数量直接等于到货数量 44 // 如果不需要检验,则合格品数量直接等于到货数量
35 - // TODO @AI:isFalase,减少反向判断;  
36 - if (!Boolean.TRUE.equals(line.getIqcCheckFlag())) { 45 + if (BooleanUtil.isFalse(line.getIqcCheckFlag())) {
37 line.setQualifiedQuantity(line.getArrivalQuantity()); 46 line.setQualifiedQuantity(line.getArrivalQuantity());
38 } 47 }
39 arrivalNoticeLineMapper.insert(line); 48 arrivalNoticeLineMapper.insert(line);
@@ -43,14 +52,14 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine @@ -43,14 +52,14 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine
43 @Override 52 @Override
44 public void updateArrivalNoticeLine(MesWmArrivalNoticeLineSaveReqVO updateReqVO) { 53 public void updateArrivalNoticeLine(MesWmArrivalNoticeLineSaveReqVO updateReqVO) {
45 // 校验存在 54 // 校验存在
46 - validateArrivalNoticeLineExists(updateReqVO.getId());  
47 - // TODO @AI:关联表的校验; 55 + MesWmArrivalNoticeLineDO line = validateArrivalNoticeLineExists(updateReqVO.getId());
  56 + // 校验父单据存在且为草稿状态
  57 + validateNoticeStatusDraft(line.getNoticeId());
48 58
49 // 更新 59 // 更新
50 MesWmArrivalNoticeLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmArrivalNoticeLineDO.class); 60 MesWmArrivalNoticeLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmArrivalNoticeLineDO.class);
51 // 如果不需要检验,则合格品数量直接等于到货数量 61 // 如果不需要检验,则合格品数量直接等于到货数量
52 - // TODO @AI:isFalase,减少反向判断;  
53 - if (!Boolean.TRUE.equals(updateObj.getIqcCheckFlag())) { 62 + if (BooleanUtil.isFalse(updateObj.getIqcCheckFlag())) {
54 updateObj.setQualifiedQuantity(updateObj.getArrivalQuantity()); 63 updateObj.setQualifiedQuantity(updateObj.getArrivalQuantity());
55 } 64 }
56 arrivalNoticeLineMapper.updateById(updateObj); 65 arrivalNoticeLineMapper.updateById(updateObj);
@@ -79,10 +88,30 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine @@ -79,10 +88,30 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine
79 return arrivalNoticeLineMapper.selectListByNoticeId(noticeId); 88 return arrivalNoticeLineMapper.selectListByNoticeId(noticeId);
80 } 89 }
81 90
82 - private void validateArrivalNoticeLineExists(Long id) {  
83 - if (arrivalNoticeLineMapper.selectById(id) == null) { 91 + @Override
  92 + public void deleteArrivalNoticeLineByNoticeId(Long noticeId) {
  93 + arrivalNoticeLineMapper.deleteByNoticeId(noticeId);
  94 + }
  95 +
  96 + private MesWmArrivalNoticeLineDO validateArrivalNoticeLineExists(Long id) {
  97 + MesWmArrivalNoticeLineDO line = arrivalNoticeLineMapper.selectById(id);
  98 + if (line == null) {
84 throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS); 99 throw exception(WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS);
85 } 100 }
  101 + return line;
  102 + }
  103 +
  104 + /**
  105 + * 校验父到货通知单存在且为草稿状态
  106 + */
  107 + private void validateNoticeStatusDraft(Long noticeId) {
  108 + MesWmArrivalNoticeDO notice = arrivalNoticeService.getArrivalNotice(noticeId);
  109 + if (notice == null) {
  110 + throw exception(WM_ARRIVAL_NOTICE_NOT_EXISTS);
  111 + }
  112 + if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.PREPARE.getStatus(), notice.getStatus())) {
  113 + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE);
  114 + }
86 } 115 }
87 116
88 } 117 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java
@@ -55,23 +55,22 @@ public interface MesWmArrivalNoticeService { @@ -55,23 +55,22 @@ public interface MesWmArrivalNoticeService {
55 */ 55 */
56 PageResult<MesWmArrivalNoticeDO> getArrivalNoticePage(MesWmArrivalNoticePageReqVO pageReqVO); 56 PageResult<MesWmArrivalNoticeDO> getArrivalNoticePage(MesWmArrivalNoticePageReqVO pageReqVO);
57 57
58 - // TODO @AI:0-》1、1-》2 尽量写状态;不要写这种;  
59 /** 58 /**
60 - * 提交到货通知单(0→1) 59 + * 提交到货通知单(草稿 → 已提交)
61 * 60 *
62 * @param id 编号 61 * @param id 编号
63 */ 62 */
64 void submitArrivalNotice(Long id); 63 void submitArrivalNotice(Long id);
65 64
66 /** 65 /**
67 - * 审批到货通知单(1→2) 66 + * 审批到货通知单(已提交 → 已审批)
68 * 67 *
69 * @param id 编号 68 * @param id 编号
70 */ 69 */
71 void approveArrivalNotice(Long id); 70 void approveArrivalNotice(Long id);
72 71
73 /** 72 /**
74 - * 完成到货通知单(→3),内部调用 73 + * 完成到货通知单(已审批 → 已完成),内部调用
75 * 74 *
76 * @param id 编号 75 * @param id 编号
77 */ 76 */
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
1 package cn.iocoder.yudao.module.mes.service.wm.arrivalnotice; 1 package cn.iocoder.yudao.module.mes.service.wm.arrivalnotice;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
4 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.collection.CollectionUtils;
5 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
6 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.MesWmArrivalNoticePageReqVO; 8 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.MesWmArrivalNoticePageReqVO;
7 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.MesWmArrivalNoticeSaveReqVO; 9 import cn.iocoder.yudao.module.mes.controller.admin.wm.arrivalnotice.vo.MesWmArrivalNoticeSaveReqVO;
8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO; 10 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeDO;
9 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO; 11 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.arrivalnotice.MesWmArrivalNoticeLineDO;
10 -import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeLineMapper;  
11 import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeMapper; 12 import cn.iocoder.yudao.module.mes.dal.mysql.wm.arrivalnotice.MesWmArrivalNoticeMapper;
  13 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmArrivalNoticeStatusEnum;
12 import jakarta.annotation.Resource; 14 import jakarta.annotation.Resource;
13 import org.springframework.stereotype.Service; 15 import org.springframework.stereotype.Service;
14 import org.springframework.transaction.annotation.Transactional; 16 import org.springframework.transaction.annotation.Transactional;
@@ -31,36 +33,27 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -31,36 +33,27 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
31 @Resource 33 @Resource
32 private MesWmArrivalNoticeMapper arrivalNoticeMapper; 34 private MesWmArrivalNoticeMapper arrivalNoticeMapper;
33 35
34 - // TODO @AI:不允许调用对方的,调用 service;  
35 @Resource 36 @Resource
36 - private MesWmArrivalNoticeLineMapper arrivalNoticeLineMapper; 37 + private MesWmArrivalNoticeLineService arrivalNoticeLineService;
37 38
38 @Override 39 @Override
39 public Long createArrivalNotice(MesWmArrivalNoticeSaveReqVO createReqVO) { 40 public Long createArrivalNotice(MesWmArrivalNoticeSaveReqVO createReqVO) {
40 // 校验编码唯一 41 // 校验编码唯一
41 validateCodeUnique(null, createReqVO.getCode()); 42 validateCodeUnique(null, createReqVO.getCode());
42 - // TODO @AI:关联数据的校验  
43 43
44 // 插入 44 // 插入
45 MesWmArrivalNoticeDO notice = BeanUtils.toBean(createReqVO, MesWmArrivalNoticeDO.class); 45 MesWmArrivalNoticeDO notice = BeanUtils.toBean(createReqVO, MesWmArrivalNoticeDO.class);
46 - // TODO @AI:使用枚举类;  
47 - notice.setStatus(0); // 草稿 46 + notice.setStatus(MesWmArrivalNoticeStatusEnum.PREPARE.getStatus());
48 arrivalNoticeMapper.insert(notice); 47 arrivalNoticeMapper.insert(notice);
49 return notice.getId(); 48 return notice.getId();
50 } 49 }
51 50
52 @Override 51 @Override
53 public void updateArrivalNotice(MesWmArrivalNoticeSaveReqVO updateReqVO) { 52 public void updateArrivalNotice(MesWmArrivalNoticeSaveReqVO updateReqVO) {
54 - // 校验存在  
55 - MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(updateReqVO.getId());  
56 - // 校验状态:只有草稿才允许修改  
57 - // TODO @AI:使用枚举类;  
58 - if (notice.getStatus() != 0) {  
59 - throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE);  
60 - } 53 + // 校验存在 + 草稿状态
  54 + validateArrivalNoticeExistsAndDraft(updateReqVO.getId());
61 // 校验编码唯一 55 // 校验编码唯一
62 validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); 56 validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
63 - // TODO @AI:关联数据的校验  
64 57
65 // 更新 58 // 更新
66 MesWmArrivalNoticeDO updateObj = BeanUtils.toBean(updateReqVO, MesWmArrivalNoticeDO.class); 59 MesWmArrivalNoticeDO updateObj = BeanUtils.toBean(updateReqVO, MesWmArrivalNoticeDO.class);
@@ -70,16 +63,11 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -70,16 +63,11 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
70 @Override 63 @Override
71 @Transactional(rollbackFor = Exception.class) 64 @Transactional(rollbackFor = Exception.class)
72 public void deleteArrivalNotice(Long id) { 65 public void deleteArrivalNotice(Long id) {
73 - // 校验存在  
74 - MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);  
75 - // 校验状态:只有草稿才允许删除 TODO @AI:抽个统一的校验+ 存在 “草稿”的方法,允许修改、删除  
76 - // TODO @AI:使用枚举类;  
77 - if (notice.getStatus() != 0) {  
78 - throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE);  
79 - } 66 + // 校验存在 + 草稿状态
  67 + validateArrivalNoticeExistsAndDraft(id);
80 68
81 // 级联删除行 69 // 级联删除行
82 - arrivalNoticeLineMapper.deleteByNoticeId(id); 70 + arrivalNoticeLineService.deleteArrivalNoticeLineByNoticeId(id);
83 // 删除 71 // 删除
84 arrivalNoticeMapper.deleteById(id); 72 arrivalNoticeMapper.deleteById(id);
85 } 73 }
@@ -95,56 +83,63 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -95,56 +83,63 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
95 } 83 }
96 84
97 @Override 85 @Override
  86 + @Transactional(rollbackFor = Exception.class)
98 public void submitArrivalNotice(Long id) { 87 public void submitArrivalNotice(Long id) {
99 - // 校验存在  
100 - MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);  
101 - if (notice.getStatus() != 0) { // TODO @AI:抽个统一的校验+ 存在 “草稿”的方法,允许修改、删除  
102 - throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE); 88 + // 1.1 校验存在 + 草稿状态
  89 + validateArrivalNoticeExistsAndDraft(id);
  90 + // 1.2 检查是否有行项目
  91 + List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(id);
  92 + if (CollUtil.isEmpty(lines)) {
  93 + throw exception(WM_ARRIVAL_NOTICE_NO_LINE);
103 } 94 }
104 95
105 - // 检查是否有行项目  
106 - // TODO @AI:搞个 count 方法,在对方 service,传递 noticeId + 状态  
107 - List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineMapper.selectListByNoticeId(id);  
108 // 检查所有行的 iqcCheckFlag:如果没有需要检验的行,则直接审批通过 96 // 检查所有行的 iqcCheckFlag:如果没有需要检验的行,则直接审批通过
109 - boolean needCheck = lines.stream().anyMatch(line -> Boolean.TRUE.equals(line.getIqcCheckFlag()));  
110 - // TODO @AI:计算 status,然后去更新; 97 + boolean needCheck = CollectionUtils.anyMatch(lines, line -> Boolean.TRUE.equals(line.getIqcCheckFlag()));
111 if (!needCheck) { 98 if (!needCheck) {
112 // 不需要检验,直接审批通过 99 // 不需要检验,直接审批通过
113 - arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO().setId(id).setStatus(2)); 100 + arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
  101 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.APPROVED.getStatus()));
114 } else { 102 } else {
115 // 需要检验,提交待审批 103 // 需要检验,提交待审批
116 - arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO().setId(id).setStatus(1)); 104 + arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
  105 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.SUBMITTED.getStatus()));
117 } 106 }
118 } 107 }
119 108
120 @Override 109 @Override
  110 + @Transactional(rollbackFor = Exception.class)
121 public void approveArrivalNotice(Long id) { 111 public void approveArrivalNotice(Long id) {
122 // 校验存在 112 // 校验存在
123 MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id); 113 MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);
124 - if (notice.getStatus() != 1) {  
125 - throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE); 114 + // 校验状态:只有已提交才允许审批
  115 + if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.SUBMITTED.getStatus(), notice.getStatus())) {
  116 + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_SUBMITTED);
126 } 117 }
127 - // TODO @AI:校验状态 + 状态;  
128 118
129 // 校验所有 iqcCheckFlag=true 的行必须 iqcId 不为空 119 // 校验所有 iqcCheckFlag=true 的行必须 iqcId 不为空
130 - // TODO @AI:对方 service ;搞个 count 方法,在对方 service,传递 noticeId + 状态;另外,看看能不能和上面的,保持 service 方法,保持统一;  
131 - List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineMapper.selectListByNoticeId(id);  
132 - boolean hasUnchecked = lines.stream()  
133 - .anyMatch(line -> Boolean.TRUE.equals(line.getIqcCheckFlag()) && line.getIqcId() == null); 120 + List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(id);
  121 + boolean hasUnchecked = CollectionUtils.anyMatch(lines,
  122 + line -> Boolean.TRUE.equals(line.getIqcCheckFlag()) && line.getIqcId() == null);
134 if (hasUnchecked) { 123 if (hasUnchecked) {
135 throw exception(WM_ARRIVAL_NOTICE_IQC_PENDING); 124 throw exception(WM_ARRIVAL_NOTICE_IQC_PENDING);
136 } 125 }
137 // 审批通过 126 // 审批通过
138 - arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO().setId(id).setStatus(2)); 127 + arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
  128 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.APPROVED.getStatus()));
139 } 129 }
140 130
141 @Override 131 @Override
142 public void finishArrivalNotice(Long id) { 132 public void finishArrivalNotice(Long id) {
143 - validateArrivalNoticeExists(id);  
144 - // TODO @AI:校验状态 + 状态; 133 + // 校验存在
  134 + MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);
  135 + // 校验状态:只有已审批才允许完成
  136 + if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.APPROVED.getStatus(), notice.getStatus())) {
  137 + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_APPROVED);
  138 + }
145 139
146 // 完成 140 // 完成
147 - arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO().setId(id).setStatus(3)); 141 + arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO()
  142 + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.FINISHED.getStatus()));
148 } 143 }
149 144
150 @Override 145 @Override
@@ -163,13 +158,23 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService @@ -163,13 +158,23 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService
163 return notice; 158 return notice;
164 } 159 }
165 160
  161 + /**
  162 + * 校验到货通知单存在且为草稿状态
  163 + */
  164 + private MesWmArrivalNoticeDO validateArrivalNoticeExistsAndDraft(Long id) {
  165 + MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id);
  166 + if (ObjUtil.notEqual(MesWmArrivalNoticeStatusEnum.PREPARE.getStatus(), notice.getStatus())) {
  167 + throw exception(WM_ARRIVAL_NOTICE_STATUS_NOT_PREPARE);
  168 + }
  169 + return notice;
  170 + }
  171 +
166 private void validateCodeUnique(Long id, String code) { 172 private void validateCodeUnique(Long id, String code) {
167 MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectByCode(code); 173 MesWmArrivalNoticeDO notice = arrivalNoticeMapper.selectByCode(code);
168 if (notice == null) { 174 if (notice == null) {
169 return; 175 return;
170 } 176 }
171 - // TODO @AI:notEquals  
172 - if (id == null || !id.equals(notice.getId())) { 177 + if (ObjUtil.notEqual(id, notice.getId())) {
173 throw exception(WM_ARRIVAL_NOTICE_CODE_DUPLICATE); 178 throw exception(WM_ARRIVAL_NOTICE_CODE_DUPLICATE);
174 } 179 }
175 } 180 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailService.java
@@ -52,6 +52,14 @@ public interface MesWmItemReceiptDetailService { @@ -52,6 +52,14 @@ public interface MesWmItemReceiptDetailService {
52 PageResult<MesWmItemReceiptDetailDO> getItemReceiptDetailPage(MesWmItemReceiptDetailPageReqVO pageReqVO); 52 PageResult<MesWmItemReceiptDetailDO> getItemReceiptDetailPage(MesWmItemReceiptDetailPageReqVO pageReqVO);
53 53
54 /** 54 /**
  55 + * 按入库单编号获得明细列表
  56 + *
  57 + * @param receiptId 入库单编号
  58 + * @return 明细列表
  59 + */
  60 + List<MesWmItemReceiptDetailDO> getItemReceiptDetailListByReceiptId(Long receiptId);
  61 +
  62 + /**
55 * 按入库单行编号获得明细列表 63 * 按入库单行编号获得明细列表
56 * 64 *
57 * @param lineId 行编号 65 * @param lineId 行编号
@@ -59,4 +67,18 @@ public interface MesWmItemReceiptDetailService { @@ -59,4 +67,18 @@ public interface MesWmItemReceiptDetailService {
59 */ 67 */
60 List<MesWmItemReceiptDetailDO> getItemReceiptDetailListByLineId(Long lineId); 68 List<MesWmItemReceiptDetailDO> getItemReceiptDetailListByLineId(Long lineId);
61 69
  70 + /**
  71 + * 按入库单行编号批量删除明细
  72 + *
  73 + * @param lineId 行编号
  74 + */
  75 + void deleteItemReceiptDetailByLineId(Long lineId);
  76 +
  77 + /**
  78 + * 按入库单编号批量删除明细
  79 + *
  80 + * @param receiptId 入库单编号
  81 + */
  82 + void deleteItemReceiptDetailByReceiptId(Long receiptId);
  83 +
62 } 84 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptDetailServiceImpl.java
@@ -4,16 +4,20 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,16 +4,20 @@ 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.module.mes.controller.admin.wm.itemreceipt.vo.detail.MesWmItemReceiptDetailPageReqVO; 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.MesWmItemReceiptDetailSaveReqVO; 6 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;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO;
8 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper; 9 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper;
  10 +import cn.hutool.core.util.ObjUtil;
  11 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
9 import jakarta.annotation.Resource; 12 import jakarta.annotation.Resource;
  13 +import org.springframework.context.annotation.Lazy;
10 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
11 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
12 16
13 import java.util.List; 17 import java.util.List;
14 18
15 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
16 -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS; 20 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
17 21
18 /** 22 /**
19 * MES 采购入库明细 Service 实现类 23 * MES 采购入库明细 Service 实现类
@@ -25,9 +29,15 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -25,9 +29,15 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
25 @Resource 29 @Resource
26 private MesWmItemReceiptDetailMapper itemReceiptDetailMapper; 30 private MesWmItemReceiptDetailMapper itemReceiptDetailMapper;
27 31
  32 + @Resource
  33 + @Lazy
  34 + private MesWmItemReceiptService itemReceiptService;
  35 +
28 @Override 36 @Override
29 public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) { 37 public Long createItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO createReqVO) {
30 - // TODO @AI:校验关联字段; 38 + // 校验父单据存在且为草稿状态
  39 + validateReceiptStatusDraft(createReqVO.getReceiptId());
  40 +
31 MesWmItemReceiptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmItemReceiptDetailDO.class); 41 MesWmItemReceiptDetailDO detail = BeanUtils.toBean(createReqVO, MesWmItemReceiptDetailDO.class);
32 itemReceiptDetailMapper.insert(detail); 42 itemReceiptDetailMapper.insert(detail);
33 return detail.getId(); 43 return detail.getId();
@@ -36,8 +46,9 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -36,8 +46,9 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
36 @Override 46 @Override
37 public void updateItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO updateReqVO) { 47 public void updateItemReceiptDetail(MesWmItemReceiptDetailSaveReqVO updateReqVO) {
38 // 校验存在 48 // 校验存在
39 - validateItemReceiptDetailExists(updateReqVO.getId());  
40 - // TODO @AI:校验关联字段; 49 + MesWmItemReceiptDetailDO detail = validateItemReceiptDetailExists(updateReqVO.getId());
  50 + // 校验父单据存在且为草稿状态
  51 + validateReceiptStatusDraft(detail.getReceiptId());
41 52
42 // 更新 53 // 更新
43 MesWmItemReceiptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDetailDO.class); 54 MesWmItemReceiptDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptDetailDO.class);
@@ -63,14 +74,44 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail @@ -63,14 +74,44 @@ public class MesWmItemReceiptDetailServiceImpl implements MesWmItemReceiptDetail
63 } 74 }
64 75
65 @Override 76 @Override
  77 + public List<MesWmItemReceiptDetailDO> getItemReceiptDetailListByReceiptId(Long receiptId) {
  78 + return itemReceiptDetailMapper.selectListByReceiptId(receiptId);
  79 + }
  80 +
  81 + @Override
66 public List<MesWmItemReceiptDetailDO> getItemReceiptDetailListByLineId(Long lineId) { 82 public List<MesWmItemReceiptDetailDO> getItemReceiptDetailListByLineId(Long lineId) {
67 return itemReceiptDetailMapper.selectListByLineId(lineId); 83 return itemReceiptDetailMapper.selectListByLineId(lineId);
68 } 84 }
69 85
70 - private void validateItemReceiptDetailExists(Long id) {  
71 - if (itemReceiptDetailMapper.selectById(id) == null) { 86 + @Override
  87 + public void deleteItemReceiptDetailByLineId(Long lineId) {
  88 + itemReceiptDetailMapper.deleteByLineId(lineId);
  89 + }
  90 +
  91 + @Override
  92 + public void deleteItemReceiptDetailByReceiptId(Long receiptId) {
  93 + itemReceiptDetailMapper.deleteByReceiptId(receiptId);
  94 + }
  95 +
  96 + private MesWmItemReceiptDetailDO validateItemReceiptDetailExists(Long id) {
  97 + MesWmItemReceiptDetailDO detail = itemReceiptDetailMapper.selectById(id);
  98 + if (detail == null) {
72 throw exception(WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS); 99 throw exception(WM_ITEM_RECEIPT_DETAIL_NOT_EXISTS);
73 } 100 }
  101 + return detail;
  102 + }
  103 +
  104 + /**
  105 + * 校验父采购入库单存在且为草稿状态
  106 + */
  107 + private void validateReceiptStatusDraft(Long receiptId) {
  108 + MesWmItemReceiptDO receipt = itemReceiptService.getItemReceipt(receiptId);
  109 + if (receipt == null) {
  110 + throw exception(WM_ITEM_RECEIPT_NOT_EXISTS);
  111 + }
  112 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())) {
  113 + throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);
  114 + }
74 } 115 }
75 116
76 } 117 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineService.java
@@ -59,4 +59,11 @@ public interface MesWmItemReceiptLineService { @@ -59,4 +59,11 @@ public interface MesWmItemReceiptLineService {
59 */ 59 */
60 List<MesWmItemReceiptLineDO> getItemReceiptLineListByReceiptId(Long receiptId); 60 List<MesWmItemReceiptLineDO> getItemReceiptLineListByReceiptId(Long receiptId);
61 61
  62 + /**
  63 + * 按入库单编号批量删除行
  64 + *
  65 + * @param receiptId 入库单编号
  66 + */
  67 + void deleteItemReceiptLineByReceiptId(Long receiptId);
  68 +
62 } 69 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptLineServiceImpl.java
@@ -4,10 +4,13 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -4,10 +4,13 @@ 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.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLinePageReqVO; 5 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLinePageReqVO;
6 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLineSaveReqVO; 6 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.line.MesWmItemReceiptLineSaveReqVO;
  7 +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; 8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO;
8 -import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper;  
9 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptLineMapper; 9 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptLineMapper;
  10 +import cn.hutool.core.util.ObjUtil;
  11 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
10 import jakarta.annotation.Resource; 12 import jakarta.annotation.Resource;
  13 +import org.springframework.context.annotation.Lazy;
11 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
12 import org.springframework.transaction.annotation.Transactional; 15 import org.springframework.transaction.annotation.Transactional;
13 import org.springframework.validation.annotation.Validated; 16 import org.springframework.validation.annotation.Validated;
@@ -15,7 +18,7 @@ import org.springframework.validation.annotation.Validated; @@ -15,7 +18,7 @@ import org.springframework.validation.annotation.Validated;
15 import java.util.List; 18 import java.util.List;
16 19
17 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
18 -import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_ITEM_RECEIPT_LINE_NOT_EXISTS; 21 +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
19 22
20 /** 23 /**
21 * MES 采购入库单行 Service 实现类 24 * MES 采购入库单行 Service 实现类
@@ -28,11 +31,16 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -28,11 +31,16 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
28 private MesWmItemReceiptLineMapper itemReceiptLineMapper; 31 private MesWmItemReceiptLineMapper itemReceiptLineMapper;
29 32
30 @Resource 33 @Resource
31 - private MesWmItemReceiptDetailMapper itemReceiptDetailMapper; 34 + @Lazy
  35 + private MesWmItemReceiptService itemReceiptService;
  36 +
  37 + @Resource
  38 + private MesWmItemReceiptDetailService itemReceiptDetailService;
32 39
33 @Override 40 @Override
34 public Long createItemReceiptLine(MesWmItemReceiptLineSaveReqVO createReqVO) { 41 public Long createItemReceiptLine(MesWmItemReceiptLineSaveReqVO createReqVO) {
35 - // TODO @AI:校验关联字段; 42 + // 校验父单据存在且为草稿状态
  43 + validateReceiptStatusDraft(createReqVO.getReceiptId());
36 44
37 // 新增 45 // 新增
38 MesWmItemReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmItemReceiptLineDO.class); 46 MesWmItemReceiptLineDO line = BeanUtils.toBean(createReqVO, MesWmItemReceiptLineDO.class);
@@ -43,8 +51,9 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -43,8 +51,9 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
43 @Override 51 @Override
44 public void updateItemReceiptLine(MesWmItemReceiptLineSaveReqVO updateReqVO) { 52 public void updateItemReceiptLine(MesWmItemReceiptLineSaveReqVO updateReqVO) {
45 // 校验存在 53 // 校验存在
46 - validateItemReceiptLineExists(updateReqVO.getId());  
47 - // TODO @AI:校验关联字段; 54 + MesWmItemReceiptLineDO line = validateItemReceiptLineExists(updateReqVO.getId());
  55 + // 校验父单据存在且为草稿状态
  56 + validateReceiptStatusDraft(line.getReceiptId());
48 57
49 // 更新 58 // 更新
50 MesWmItemReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptLineDO.class); 59 MesWmItemReceiptLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmItemReceiptLineDO.class);
@@ -58,7 +67,7 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -58,7 +67,7 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
58 validateItemReceiptLineExists(id); 67 validateItemReceiptLineExists(id);
59 68
60 // 级联删除明细 69 // 级联删除明细
61 - itemReceiptDetailMapper.deleteByLineId(id); 70 + itemReceiptDetailService.deleteItemReceiptDetailByLineId(id);
62 // 删除 71 // 删除
63 itemReceiptLineMapper.deleteById(id); 72 itemReceiptLineMapper.deleteById(id);
64 } 73 }
@@ -78,10 +87,30 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ @@ -78,10 +87,30 @@ public class MesWmItemReceiptLineServiceImpl implements MesWmItemReceiptLineServ
78 return itemReceiptLineMapper.selectListByReceiptId(receiptId); 87 return itemReceiptLineMapper.selectListByReceiptId(receiptId);
79 } 88 }
80 89
81 - private void validateItemReceiptLineExists(Long id) {  
82 - if (itemReceiptLineMapper.selectById(id) == null) { 90 + @Override
  91 + public void deleteItemReceiptLineByReceiptId(Long receiptId) {
  92 + itemReceiptLineMapper.deleteByReceiptId(receiptId);
  93 + }
  94 +
  95 + private MesWmItemReceiptLineDO validateItemReceiptLineExists(Long id) {
  96 + MesWmItemReceiptLineDO line = itemReceiptLineMapper.selectById(id);
  97 + if (line == null) {
83 throw exception(WM_ITEM_RECEIPT_LINE_NOT_EXISTS); 98 throw exception(WM_ITEM_RECEIPT_LINE_NOT_EXISTS);
84 } 99 }
  100 + return line;
  101 + }
  102 +
  103 + /**
  104 + * 校验父采购入库单存在且为草稿状态
  105 + */
  106 + private void validateReceiptStatusDraft(Long receiptId) {
  107 + MesWmItemReceiptDO receipt = itemReceiptService.getItemReceipt(receiptId);
  108 + if (receipt == null) {
  109 + throw exception(WM_ITEM_RECEIPT_NOT_EXISTS);
  110 + }
  111 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())) {
  112 + throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);
  113 + }
85 } 114 }
86 115
87 } 116 }
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptService.java
@@ -49,25 +49,22 @@ public interface MesWmItemReceiptService { @@ -49,25 +49,22 @@ public interface MesWmItemReceiptService {
49 */ 49 */
50 PageResult<MesWmItemReceiptDO> getItemReceiptPage(MesWmItemReceiptPageReqVO pageReqVO); 50 PageResult<MesWmItemReceiptDO> getItemReceiptPage(MesWmItemReceiptPageReqVO pageReqVO);
51 51
52 - // TODO @AI:0-》1、1-》2 尽量写状态;不要写这种;  
53 /** 52 /**
54 - * 提交采购入库单(0→1) 53 + * 提交采购入库单(草稿 → 已提交)
55 * 54 *
56 * @param id 编号 55 * @param id 编号
57 */ 56 */
58 void submitItemReceipt(Long id); 57 void submitItemReceipt(Long id);
59 58
60 - // TODO @AI:0-》1、1-》2 尽量写状态;不要写这种;  
61 /** 59 /**
62 - * 审批采购入库单(1→2) 60 + * 审批采购入库单(已提交 → 已审批)
63 * 61 *
64 * @param id 编号 62 * @param id 编号
65 */ 63 */
66 void approveItemReceipt(Long id); 64 void approveItemReceipt(Long id);
67 65
68 - // TODO @AI:0-》1、1-》2 尽量写状态;不要写这种;  
69 /** 66 /**
70 - * 执行入库(2→3),更新库存台账 67 + * 执行入库(已审批 → 已完成),更新库存台账
71 * 68 *
72 * @param id 编号 69 * @param id 编号
73 */ 70 */
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
1 package cn.iocoder.yudao.module.mes.service.wm.itemreceipt; 1 package cn.iocoder.yudao.module.mes.service.wm.itemreceipt;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.ObjUtil;
3 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.collection.CollectionUtils;
4 import cn.iocoder.yudao.framework.common.util.object.BeanUtils; 7 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
5 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptPageReqVO; 8 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptPageReqVO;
6 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptSaveReqVO; 9 import cn.iocoder.yudao.module.mes.controller.admin.wm.itemreceipt.vo.MesWmItemReceiptSaveReqVO;
7 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO; 10 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDO;
8 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO; 11 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptDetailDO;
9 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO; 12 import cn.iocoder.yudao.module.mes.dal.dataobject.wm.itemreceipt.MesWmItemReceiptLineDO;
10 -import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptDetailMapper;  
11 -import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptLineMapper;  
12 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapper; 13 import cn.iocoder.yudao.module.mes.dal.mysql.wm.itemreceipt.MesWmItemReceiptMapper;
  14 +import cn.iocoder.yudao.module.mes.enums.wm.MesWmItemReceiptStatusEnum;
13 import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService; 15 import cn.iocoder.yudao.module.mes.service.wm.arrivalnotice.MesWmArrivalNoticeService;
14 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService; 16 import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
15 import jakarta.annotation.Resource; 17 import jakarta.annotation.Resource;
@@ -35,10 +37,10 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -35,10 +37,10 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
35 private MesWmItemReceiptMapper itemReceiptMapper; 37 private MesWmItemReceiptMapper itemReceiptMapper;
36 38
37 @Resource 39 @Resource
38 - private MesWmItemReceiptLineMapper itemReceiptLineMapper; 40 + private MesWmItemReceiptLineService itemReceiptLineService;
39 41
40 @Resource 42 @Resource
41 - private MesWmItemReceiptDetailMapper itemReceiptDetailMapper; 43 + private MesWmItemReceiptDetailService itemReceiptDetailService;
42 44
43 @Resource 45 @Resource
44 @Lazy 46 @Lazy
@@ -51,25 +53,18 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -51,25 +53,18 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
51 public Long createItemReceipt(MesWmItemReceiptSaveReqVO createReqVO) { 53 public Long createItemReceipt(MesWmItemReceiptSaveReqVO createReqVO) {
52 // 校验编码唯一 54 // 校验编码唯一
53 validateCodeUnique(null, createReqVO.getCode()); 55 validateCodeUnique(null, createReqVO.getCode());
54 - // TODO @AI:校验关联字段;  
55 56
56 // 插入 57 // 插入
57 MesWmItemReceiptDO receipt = BeanUtils.toBean(createReqVO, MesWmItemReceiptDO.class); 58 MesWmItemReceiptDO receipt = BeanUtils.toBean(createReqVO, MesWmItemReceiptDO.class);
58 - receipt.setStatus(0); // 草稿 TODO @AI:使用枚举类 59 + receipt.setStatus(MesWmItemReceiptStatusEnum.PREPARE.getStatus());
59 itemReceiptMapper.insert(receipt); 60 itemReceiptMapper.insert(receipt);
60 return receipt.getId(); 61 return receipt.getId();
61 } 62 }
62 63
63 @Override 64 @Override
64 public void updateItemReceipt(MesWmItemReceiptSaveReqVO updateReqVO) { 65 public void updateItemReceipt(MesWmItemReceiptSaveReqVO updateReqVO) {
65 - // 校验存在  
66 - MesWmItemReceiptDO receipt = validateItemReceiptExists(updateReqVO.getId());  
67 - // TODO @AI:校验关联字段;  
68 - // 校验状态:只有草稿才允许修改  
69 - // TODO @AI:校验状态,看看抽个方法,尽量几个方法复用  
70 - if (receipt.getStatus() != 0) {  
71 - throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);  
72 - } 66 + // 校验存在 + 草稿状态
  67 + validateItemReceiptExistsAndDraft(updateReqVO.getId());
73 // 校验编码唯一 68 // 校验编码唯一
74 validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode()); 69 validateCodeUnique(updateReqVO.getId(), updateReqVO.getCode());
75 70
@@ -81,17 +76,12 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -81,17 +76,12 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
81 @Override 76 @Override
82 @Transactional(rollbackFor = Exception.class) 77 @Transactional(rollbackFor = Exception.class)
83 public void deleteItemReceipt(Long id) { 78 public void deleteItemReceipt(Long id) {
84 - // 校验存在  
85 - MesWmItemReceiptDO receipt = validateItemReceiptExists(id);  
86 - // 校验状态:只有草稿才允许删除  
87 - // TODO @AI:校验状态,看看抽个方法,尽量几个方法复用  
88 - if (receipt.getStatus() != 0) {  
89 - throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);  
90 - } 79 + // 校验存在 + 草稿状态
  80 + validateItemReceiptExistsAndDraft(id);
91 81
92 // 级联删除明细和行 82 // 级联删除明细和行
93 - itemReceiptDetailMapper.deleteByReceiptId(id);  
94 - itemReceiptLineMapper.deleteByReceiptId(id); 83 + itemReceiptDetailService.deleteItemReceiptDetailByReceiptId(id);
  84 + itemReceiptLineService.deleteItemReceiptLineByReceiptId(id);
95 // 删除 85 // 删除
96 itemReceiptMapper.deleteById(id); 86 itemReceiptMapper.deleteById(id);
97 } 87 }
@@ -107,47 +97,43 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -107,47 +97,43 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
107 } 97 }
108 98
109 @Override 99 @Override
  100 + @Transactional(rollbackFor = Exception.class)
110 public void submitItemReceipt(Long id) { 101 public void submitItemReceipt(Long id) {
111 - // 校验存在  
112 - MesWmItemReceiptDO receipt = validateItemReceiptExists(id);  
113 - // TODO @AI:校验状态,看看抽个方法,尽量几个方法复用  
114 - if (receipt.getStatus() != 0) {  
115 - throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);  
116 - } 102 + // 校验存在 + 草稿状态
  103 + validateItemReceiptExistsAndDraft(id);
117 // 校验至少有一条行 104 // 校验至少有一条行
118 - // TODO @AI:对方抽个计算数量的方法啊;  
119 - List<MesWmItemReceiptLineDO> lines = itemReceiptLineMapper.selectListByReceiptId(id);  
120 - if (lines.isEmpty()) { 105 + List<MesWmItemReceiptLineDO> lines = itemReceiptLineService.getItemReceiptLineListByReceiptId(id);
  106 + if (CollUtil.isEmpty(lines)) {
121 throw exception(WM_ITEM_RECEIPT_NO_LINE); 107 throw exception(WM_ITEM_RECEIPT_NO_LINE);
122 } 108 }
123 109
124 // 提交 110 // 提交
125 - itemReceiptMapper.updateById(new MesWmItemReceiptDO().setId(id).setStatus(1)); 111 + itemReceiptMapper.updateById(new MesWmItemReceiptDO()
  112 + .setId(id).setStatus(MesWmItemReceiptStatusEnum.SUBMITTED.getStatus()));
126 } 113 }
127 114
128 @Override 115 @Override
  116 + @Transactional(rollbackFor = Exception.class)
129 public void approveItemReceipt(Long id) { 117 public void approveItemReceipt(Long id) {
130 // 校验存在 118 // 校验存在
131 MesWmItemReceiptDO receipt = validateItemReceiptExists(id); 119 MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
132 - // TODO @AI:抽一些校验的存在+状态方法  
133 - if (receipt.getStatus() != 1) { 120 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.SUBMITTED.getStatus(), receipt.getStatus())) {
134 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR); 121 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR);
135 } 122 }
136 // 校验每行的 SUM(detail.quantity) = line.receivedQuantity 123 // 校验每行的 SUM(detail.quantity) = line.receivedQuantity
137 - // TODO @AI:抽个计算的 count 方法,然后在行和明细都用;不然代码里到处都是计算的逻辑;  
138 - List<MesWmItemReceiptLineDO> lines = itemReceiptLineMapper.selectListByReceiptId(id); 124 + List<MesWmItemReceiptLineDO> lines = itemReceiptLineService.getItemReceiptLineListByReceiptId(id);
139 for (MesWmItemReceiptLineDO line : lines) { 125 for (MesWmItemReceiptLineDO line : lines) {
140 - List<MesWmItemReceiptDetailDO> details = itemReceiptDetailMapper.selectListByLineId(line.getId());  
141 - BigDecimal totalDetailQty = details.stream()  
142 - .map(MesWmItemReceiptDetailDO::getQuantity)  
143 - .reduce(BigDecimal.ZERO, BigDecimal::add); 126 + List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByLineId(line.getId());
  127 + BigDecimal totalDetailQty = CollectionUtils.getSumValue(details,
  128 + MesWmItemReceiptDetailDO::getQuantity, BigDecimal::add, BigDecimal.ZERO);
144 if (line.getReceivedQuantity() != null && totalDetailQty.compareTo(line.getReceivedQuantity()) != 0) { 129 if (line.getReceivedQuantity() != null && totalDetailQty.compareTo(line.getReceivedQuantity()) != 0) {
145 throw exception(WM_ITEM_RECEIPT_DETAIL_QUANTITY_MISMATCH); 130 throw exception(WM_ITEM_RECEIPT_DETAIL_QUANTITY_MISMATCH);
146 } 131 }
147 } 132 }
148 133
149 // 审批 134 // 审批
150 - itemReceiptMapper.updateById(new MesWmItemReceiptDO().setId(id).setStatus(2)); 135 + itemReceiptMapper.updateById(new MesWmItemReceiptDO()
  136 + .setId(id).setStatus(MesWmItemReceiptStatusEnum.APPROVED.getStatus()));
151 } 137 }
152 138
153 @Override 139 @Override
@@ -155,14 +141,12 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -155,14 +141,12 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
155 public void executeItemReceipt(Long id) { 141 public void executeItemReceipt(Long id) {
156 // 校验存在 142 // 校验存在
157 MesWmItemReceiptDO receipt = validateItemReceiptExists(id); 143 MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
158 - // TODO @AI:抽一些校验的存在+状态方法  
159 - if (receipt.getStatus() != 2) { 144 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.APPROVED.getStatus(), receipt.getStatus())) {
160 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR); 145 throw exception(WM_ITEM_RECEIPT_STATUS_ERROR);
161 } 146 }
162 147
163 // 遍历所有明细,更新库存台账 148 // 遍历所有明细,更新库存台账
164 - // TODO @AI:select 方法,对方搞个;  
165 - List<MesWmItemReceiptDetailDO> details = itemReceiptDetailMapper.selectListByReceiptId(id); 149 + List<MesWmItemReceiptDetailDO> details = itemReceiptDetailService.getItemReceiptDetailListByReceiptId(id);
166 for (MesWmItemReceiptDetailDO detail : details) { 150 for (MesWmItemReceiptDetailDO detail : details) {
167 materialStockService.increaseStock( 151 materialStockService.increaseStock(
168 detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(), 152 detail.getItemId(), detail.getWarehouseId(), detail.getLocationId(), detail.getAreaId(),
@@ -170,8 +154,8 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -170,8 +154,8 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
170 } 154 }
171 155
172 // 更新入库单状态 156 // 更新入库单状态
173 - // TODO @AI:枚举类;  
174 - itemReceiptMapper.updateById(new MesWmItemReceiptDO().setId(id).setStatus(3)); 157 + itemReceiptMapper.updateById(new MesWmItemReceiptDO()
  158 + .setId(id).setStatus(MesWmItemReceiptStatusEnum.FINISHED.getStatus()));
175 // 更新关联的到货通知单状态 159 // 更新关联的到货通知单状态
176 if (receipt.getNoticeId() != null) { 160 if (receipt.getNoticeId() != null) {
177 arrivalNoticeService.finishArrivalNotice(receipt.getNoticeId()); 161 arrivalNoticeService.finishArrivalNotice(receipt.getNoticeId());
@@ -186,13 +170,23 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService { @@ -186,13 +170,23 @@ public class MesWmItemReceiptServiceImpl implements MesWmItemReceiptService {
186 return receipt; 170 return receipt;
187 } 171 }
188 172
  173 + /**
  174 + * 校验采购入库单存在且为草稿状态
  175 + */
  176 + private MesWmItemReceiptDO validateItemReceiptExistsAndDraft(Long id) {
  177 + MesWmItemReceiptDO receipt = validateItemReceiptExists(id);
  178 + if (ObjUtil.notEqual(MesWmItemReceiptStatusEnum.PREPARE.getStatus(), receipt.getStatus())) {
  179 + throw exception(WM_ITEM_RECEIPT_STATUS_NOT_PREPARE);
  180 + }
  181 + return receipt;
  182 + }
  183 +
189 private void validateCodeUnique(Long id, String code) { 184 private void validateCodeUnique(Long id, String code) {
190 MesWmItemReceiptDO receipt = itemReceiptMapper.selectByCode(code); 185 MesWmItemReceiptDO receipt = itemReceiptMapper.selectByCode(code);
191 if (receipt == null) { 186 if (receipt == null) {
192 return; 187 return;
193 } 188 }
194 - // TODO @AI:ObjUtil notEquals  
195 - if (id == null || !id.equals(receipt.getId())) { 189 + if (ObjUtil.notEqual(id, receipt.getId())) {
196 throw exception(WM_ITEM_RECEIPT_CODE_DUPLICATE); 190 throw exception(WM_ITEM_RECEIPT_CODE_DUPLICATE);
197 } 191 }
198 } 192 }