Commit d6d6887bdffe1be5be08f00e27f7bedd41e77478
1 parent
fa473f7d
✨ feat(mes): 将质量状态字段类型更新为整型,优化数据一致性
Showing
46 changed files
with
970 additions
and
127 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcRespVO.java
| ... | ... | @@ -33,8 +33,8 @@ public class MesQcOqcRespVO { |
| 33 | 33 | @Schema(description = "来源单据 ID", example = "200") |
| 34 | 34 | private Long sourceDocId; |
| 35 | 35 | |
| 36 | - @Schema(description = "来源单据类型", example = "SALES") | |
| 37 | - private String sourceDocType; | |
| 36 | + @Schema(description = "来源单据类型", example = "118") | |
| 37 | + private Integer sourceDocType; | |
| 38 | 38 | |
| 39 | 39 | @Schema(description = "来源单据编号", example = "SO20250101001") |
| 40 | 40 | private String sourceDocCode; |
| ... | ... | @@ -88,15 +88,15 @@ public class MesQcOqcRespVO { |
| 88 | 88 | |
| 89 | 89 | @Schema(description = "本次检测数量", example = "10") |
| 90 | 90 | @ExcelProperty("检测数量") |
| 91 | - private Integer checkQuantity; | |
| 91 | + private BigDecimal checkQuantity; | |
| 92 | 92 | |
| 93 | 93 | @Schema(description = "合格品数量", example = "9") |
| 94 | 94 | @ExcelProperty("合格品数量") |
| 95 | - private Integer qualifiedQuantity; | |
| 95 | + private BigDecimal qualifiedQuantity; | |
| 96 | 96 | |
| 97 | 97 | @Schema(description = "不合格品数量", example = "1") |
| 98 | 98 | @ExcelProperty("不合格品数量") |
| 99 | - private Integer unqualifiedQuantity; | |
| 99 | + private BigDecimal unqualifiedQuantity; | |
| 100 | 100 | |
| 101 | 101 | // ========== 缺陷统计 ========== |
| 102 | 102 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/oqc/vo/MesQcOqcSaveReqVO.java
| ... | ... | @@ -29,8 +29,8 @@ public class MesQcOqcSaveReqVO { |
| 29 | 29 | @Schema(description = "来源单据 ID", example = "200") |
| 30 | 30 | private Long sourceDocId; |
| 31 | 31 | |
| 32 | - @Schema(description = "来源单据类型", example = "SALES") | |
| 33 | - private String sourceDocType; | |
| 32 | + @Schema(description = "来源单据类型", example = "118") | |
| 33 | + private Integer sourceDocType; | |
| 34 | 34 | |
| 35 | 35 | @Schema(description = "来源单据编号", example = "SO20250101001") |
| 36 | 36 | private String sourceDocCode; |
| ... | ... | @@ -62,18 +62,18 @@ public class MesQcOqcSaveReqVO { |
| 62 | 62 | |
| 63 | 63 | @Schema(description = "本次检测数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| 64 | 64 | @NotNull(message = "本次检测数量不能为空") |
| 65 | - @Min(value = 1, message = "本次检测数量必须大于 0") | |
| 66 | - private Integer checkQuantity; | |
| 65 | + @DecimalMin(value = "0", message = "本次检测数量不能小于 0") | |
| 66 | + private BigDecimal checkQuantity; | |
| 67 | 67 | |
| 68 | 68 | @Schema(description = "合格品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "9") |
| 69 | 69 | @NotNull(message = "合格品数量不能为空") |
| 70 | - @Min(value = 0, message = "合格品数量不能小于 0") | |
| 71 | - private Integer qualifiedQuantity; | |
| 70 | + @DecimalMin(value = "0", message = "合格品数量不能小于 0") | |
| 71 | + private BigDecimal qualifiedQuantity; | |
| 72 | 72 | |
| 73 | 73 | @Schema(description = "不合格品数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 74 | 74 | @NotNull(message = "不合格品数量不能为空") |
| 75 | - @Min(value = 0, message = "不合格品数量不能小于 0") | |
| 76 | - private Integer unqualifiedQuantity; | |
| 75 | + @DecimalMin(value = "0", message = "不合格品数量不能小于 0") | |
| 76 | + private BigDecimal unqualifiedQuantity; | |
| 77 | 77 | |
| 78 | 78 | // ========== 检验 ========== |
| 79 | 79 | |
| ... | ... | @@ -101,7 +101,7 @@ public class MesQcOqcSaveReqVO { |
| 101 | 101 | if (ObjUtil.hasNull(checkQuantity, qualifiedQuantity, unqualifiedQuantity)) { |
| 102 | 102 | return true; // @NotNull 会处理 null |
| 103 | 103 | } |
| 104 | - return checkQuantity.equals(qualifiedQuantity + unqualifiedQuantity); | |
| 104 | + return checkQuantity.compareTo(qualifiedQuantity.add(unqualifiedQuantity)) == 0; | |
| 105 | 105 | } |
| 106 | 106 | |
| 107 | 107 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/vo/MesQcRqcRespVO.java
| ... | ... | @@ -33,8 +33,8 @@ public class MesQcRqcRespVO { |
| 33 | 33 | @Schema(description = "来源单据 ID", example = "200") |
| 34 | 34 | private Long sourceDocId; |
| 35 | 35 | |
| 36 | - @Schema(description = "来源单据类型", example = "RTISSUE") | |
| 37 | - private String sourceDocType; | |
| 36 | + @Schema(description = "来源单据类型", example = "116") | |
| 37 | + private Integer sourceDocType; | |
| 38 | 38 | |
| 39 | 39 | @Schema(description = "来源单据行 ID", example = "300") |
| 40 | 40 | private Long sourceLineId; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/vo/MesQcRqcSaveReqVO.java
| ... | ... | @@ -35,8 +35,8 @@ public class MesQcRqcSaveReqVO { |
| 35 | 35 | @Schema(description = "来源单据 ID", example = "200") |
| 36 | 36 | private Long sourceDocId; |
| 37 | 37 | |
| 38 | - @Schema(description = "来源单据类型", example = "RTISSUE") | |
| 39 | - private String sourceDocType; | |
| 38 | + @Schema(description = "来源单据类型", example = "116") | |
| 39 | + private Integer sourceDocType; | |
| 40 | 40 | |
| 41 | 41 | @Schema(description = "来源单据行 ID", example = "300") |
| 42 | 42 | private Long sourceLineId; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchGenerateReqVO.java
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/batch/vo/MesWmBatchRespVO.java
| ... | ... | @@ -88,7 +88,7 @@ public class MesWmBatchRespVO { |
| 88 | 88 | private String lotNumber; |
| 89 | 89 | |
| 90 | 90 | @Schema(description = "质量状态", example = "1") |
| 91 | - private String qualityStatus; | |
| 91 | + private Integer qualityStatus; | |
| 92 | 92 | |
| 93 | 93 | @Schema(description = "备注", example = "备注") |
| 94 | 94 | private String remark; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/line/MesWmReturnSalesLineRespVO.java
| ... | ... | @@ -46,7 +46,7 @@ public class MesWmReturnSalesLineRespVO { |
| 46 | 46 | private String batchCode; |
| 47 | 47 | |
| 48 | 48 | @Schema(description = "质量状态", example = "合格") |
| 49 | - private String qualityStatus; | |
| 49 | + private Integer qualityStatus; | |
| 50 | 50 | |
| 51 | 51 | @Schema(description = "备注", example = "备注") |
| 52 | 52 | private String remark; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/wm/returnsales/vo/line/MesWmReturnSalesLineSaveReqVO.java
| ... | ... | @@ -36,7 +36,7 @@ public class MesWmReturnSalesLineSaveReqVO { |
| 36 | 36 | private Long batchId; |
| 37 | 37 | |
| 38 | 38 | @Schema(description = "质量状态", example = "合格") |
| 39 | - private String qualityStatus; | |
| 39 | + private Integer qualityStatus; | |
| 40 | 40 | |
| 41 | 41 | @Schema(description = "备注", example = "备注") |
| 42 | 42 | private String remark; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/oqc/MesQcOqcDO.java
| ... | ... | @@ -47,7 +47,7 @@ public class MesQcOqcDO extends BaseDO { |
| 47 | 47 | */ |
| 48 | 48 | private Long templateId; |
| 49 | 49 | |
| 50 | - // ========== 来源单据(TODO @芋艿:WM 模块迁移后接入) ========== | |
| 50 | + // ========== 来源单据 ========== | |
| 51 | 51 | |
| 52 | 52 | /** |
| 53 | 53 | * 来源单据 ID |
| ... | ... | @@ -55,8 +55,10 @@ public class MesQcOqcDO extends BaseDO { |
| 55 | 55 | private Long sourceDocId; |
| 56 | 56 | /** |
| 57 | 57 | * 来源单据类型 |
| 58 | + * | |
| 59 | + * 关联 {@link cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants} | |
| 58 | 60 | */ |
| 59 | - private String sourceDocType; | |
| 61 | + private Integer sourceDocType; | |
| 60 | 62 | /** |
| 61 | 63 | * 来源单据编号 |
| 62 | 64 | */ |
| ... | ... | @@ -97,15 +99,15 @@ public class MesQcOqcDO extends BaseDO { |
| 97 | 99 | /** |
| 98 | 100 | * 本次检测数量 |
| 99 | 101 | */ |
| 100 | - private Integer checkQuantity; | |
| 102 | + private BigDecimal checkQuantity; | |
| 101 | 103 | /** |
| 102 | 104 | * 合格品数量 |
| 103 | 105 | */ |
| 104 | - private Integer qualifiedQuantity; | |
| 106 | + private BigDecimal qualifiedQuantity; | |
| 105 | 107 | /** |
| 106 | 108 | * 不合格品数量 |
| 107 | 109 | */ |
| 108 | - private Integer unqualifiedQuantity; | |
| 110 | + private BigDecimal unqualifiedQuantity; | |
| 109 | 111 | |
| 110 | 112 | // ========== 缺陷统计 ========== |
| 111 | 113 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/qc/rqc/MesQcRqcDO.java
| ... | ... | @@ -47,7 +47,7 @@ public class MesQcRqcDO extends BaseDO { |
| 47 | 47 | */ |
| 48 | 48 | private Long templateId; |
| 49 | 49 | |
| 50 | - // ========== 来源单据(TODO @芋艿:WM 模块迁移后接入) ========== | |
| 50 | + // ========== 来源单据 ========== | |
| 51 | 51 | |
| 52 | 52 | /** |
| 53 | 53 | * 来源单据 ID |
| ... | ... | @@ -55,8 +55,10 @@ public class MesQcRqcDO extends BaseDO { |
| 55 | 55 | private Long sourceDocId; |
| 56 | 56 | /** |
| 57 | 57 | * 来源单据类型 |
| 58 | + * | |
| 59 | + * 关联 {@link cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants} | |
| 58 | 60 | */ |
| 59 | - private String sourceDocType; | |
| 61 | + private Integer sourceDocType; | |
| 60 | 62 | /** |
| 61 | 63 | * 来源单据行 ID |
| 62 | 64 | */ | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/batch/MesWmBatchDO.java
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/productsales/MesWmProductSalesLineDO.java
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/dal/dataobject/wm/returnsales/MesWmReturnSalesLineDO.java
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| ... | ... | @@ -312,6 +312,7 @@ public interface ErrorCodeConstants { |
| 312 | 312 | ErrorCode QC_OQC_NOT_PREPARE = new ErrorCode(1_040_607_002, "只有草稿状态的检验单才可操作"); |
| 313 | 313 | ErrorCode QC_OQC_QUANTITY_MISMATCH = new ErrorCode(1_040_607_004, "合格品与不合格品数量之和须等于检测数量"); |
| 314 | 314 | ErrorCode QC_OQC_NO_TEMPLATE = new ErrorCode(1_040_607_005, "当前产品未配置 OQC 检测模板"); |
| 315 | + ErrorCode QC_OQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_607_006, "完成检验单前,检测结果必须填写"); | |
| 315 | 316 | // ========== MES 质量管理-出货检验行(1-040-607-100) ========== |
| 316 | 317 | ErrorCode QC_OQC_LINE_NOT_EXISTS = new ErrorCode(1_040_607_100, "出货检验行不存在"); |
| 317 | 318 | |
| ... | ... | @@ -321,6 +322,7 @@ public interface ErrorCodeConstants { |
| 321 | 322 | ErrorCode QC_RQC_NOT_PREPARE = new ErrorCode(1_040_608_002, "只有草稿状态的检验单才可操作"); |
| 322 | 323 | ErrorCode QC_RQC_QUANTITY_MISMATCH = new ErrorCode(1_040_608_004, "合格品与不合格品数量之和须等于检测数量"); |
| 323 | 324 | ErrorCode QC_RQC_NO_TEMPLATE = new ErrorCode(1_040_608_005, "当前产品未配置 RQC 检测模板"); |
| 325 | + ErrorCode QC_RQC_CHECK_RESULT_EMPTY = new ErrorCode(1_040_608_006, "完成检验单前,检测结果必须填写"); | |
| 324 | 326 | // ========== MES 质量管理-退货检验行(1-040-608-100) ========== |
| 325 | 327 | ErrorCode QC_RQC_LINE_NOT_EXISTS = new ErrorCode(1_040_608_100, "退货检验行不存在"); |
| 326 | 328 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmArrivalNoticeStatusEnum.java
| ... | ... | @@ -36,7 +36,7 @@ public enum MesWmArrivalNoticeStatusEnum implements ArrayValuable<Integer> { |
| 36 | 36 | * |
| 37 | 37 | * 对应方法: |
| 38 | 38 | * 1. 不需要检验时:{@link MesWmArrivalNoticeService#submitArrivalNotice(Long)} |
| 39 | - * 2. 或检验完成时:{@link MesWmArrivalNoticeService#approveArrivalNoticeWhenIqcComplete(Long, Long, Long, BigDecimal)} | |
| 39 | + * 2. 或检验完成时:{@link MesWmArrivalNoticeService#updateArrivalNoticeWhenIqcFinish(Long, Long, Long, BigDecimal)} | |
| 40 | 40 | */ |
| 41 | 41 | PENDING_RECEIPT(MesOrderStatusConstants.APPROVED, "待入库"), |
| 42 | 42 | /** | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackService.java
| ... | ... | @@ -102,8 +102,8 @@ public interface MesProFeedbackService { |
| 102 | 102 | * @param materialScrapQty 料废数量 |
| 103 | 103 | * @param otherScrapQty 其他废品数量 |
| 104 | 104 | */ |
| 105 | - void completeFeedbackFromIpqc(Long feedbackId, BigDecimal qualifiedQty, BigDecimal unqualifiedQty, | |
| 106 | - BigDecimal laborScrapQty, BigDecimal materialScrapQty, BigDecimal otherScrapQty); | |
| 105 | + void updateProFeedbackWhenIpqcFinish(Long feedbackId, BigDecimal qualifiedQty, BigDecimal unqualifiedQty, | |
| 106 | + BigDecimal laborScrapQty, BigDecimal materialScrapQty, BigDecimal otherScrapQty); | |
| 107 | 107 | |
| 108 | 108 | } |
| 109 | 109 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImpl.java
| ... | ... | @@ -285,8 +285,8 @@ public class MesProFeedbackServiceImpl implements MesProFeedbackService { |
| 285 | 285 | |
| 286 | 286 | @Override |
| 287 | 287 | @Transactional(rollbackFor = Exception.class) |
| 288 | - public void completeFeedbackFromIpqc(Long feedbackId, BigDecimal qualifiedQty, BigDecimal unqualifiedQty, | |
| 289 | - BigDecimal laborScrapQty, BigDecimal materialScrapQty, BigDecimal otherScrapQty) { | |
| 288 | + public void updateProFeedbackWhenIpqcFinish(Long feedbackId, BigDecimal qualifiedQty, BigDecimal unqualifiedQty, | |
| 289 | + BigDecimal laborScrapQty, BigDecimal materialScrapQty, BigDecimal otherScrapQty) { | |
| 290 | 290 | // 1. 校验报工单存在且为待检验状态 |
| 291 | 291 | MesProFeedbackDO feedback = validateFeedbackExists(feedbackId); |
| 292 | 292 | if (ObjUtil.notEqual(feedback.getStatus(), MesProFeedbackStatusEnum.UNCHECK.getStatus())) { | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImpl.java
| ... | ... | @@ -155,7 +155,7 @@ public class MesQcIpqcServiceImpl implements MesQcIpqcService { |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | 157 | if (Objects.equals(ipqc.getSourceDocType(), MesBizTypeConstants.PRO_FEEDBACK)) { |
| 158 | - feedbackService.completeFeedbackFromIpqc(ipqc.getSourceDocId(), | |
| 158 | + feedbackService.updateProFeedbackWhenIpqcFinish(ipqc.getSourceDocId(), | |
| 159 | 159 | ObjectUtil.defaultIfNull(ipqc.getQualifiedQuantity(), BigDecimal.ZERO), |
| 160 | 160 | ObjectUtil.defaultIfNull(ipqc.getUnqualifiedQuantity(), BigDecimal.ZERO), |
| 161 | 161 | ObjectUtil.defaultIfNull(ipqc.getLaborScrapQuantity(), BigDecimal.ZERO), | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImpl.java
| ... | ... | @@ -148,10 +148,10 @@ public class MesQcIqcServiceImpl implements MesQcIqcService { |
| 148 | 148 | |
| 149 | 149 | // 根据不同的来源单据类型,回写不同的单据 |
| 150 | 150 | if (Objects.equals(iqc.getSourceDocType(), MesBizTypeConstants.WM_ARRIVAL_NOTICE)) { |
| 151 | - arrivalNoticeService.approveArrivalNoticeWhenIqcComplete(iqc.getSourceDocId(), iqc.getSourceLineId(), | |
| 151 | + arrivalNoticeService.updateArrivalNoticeWhenIqcFinish(iqc.getSourceDocId(), iqc.getSourceLineId(), | |
| 152 | 152 | iqc.getId(), iqc.getQualifiedQuantity()); |
| 153 | 153 | } else if (Objects.equals(iqc.getSourceDocType(), MesBizTypeConstants.WM_OUTSOURCE_RECPT)) { |
| 154 | - outsourceReceiptService.approveOutsourceReceiptWhenIqcComplete(iqc.getSourceDocId(), iqc.getSourceLineId(), | |
| 154 | + outsourceReceiptService.updateOutsourceReceiptWhenIqcFinish(iqc.getSourceDocId(), iqc.getSourceLineId(), | |
| 155 | 155 | iqc.getId(), iqc.getQualifiedQuantity(), iqc.getUnqualifiedQuantity()); |
| 156 | 156 | } else { |
| 157 | 157 | throw new IllegalArgumentException( | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImpl.java
| ... | ... | @@ -12,10 +12,12 @@ import cn.iocoder.yudao.module.mes.dal.mysql.qc.oqc.MesQcOqcMapper; |
| 12 | 12 | import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; |
| 13 | 13 | import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; |
| 14 | 14 | import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; |
| 15 | +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | |
| 15 | 16 | import cn.iocoder.yudao.module.mes.service.md.client.MesMdClientService; |
| 16 | 17 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 17 | 18 | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; |
| 18 | 19 | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateDetailService; |
| 20 | +import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService; | |
| 19 | 21 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 20 | 22 | import jakarta.annotation.Resource; |
| 21 | 23 | import org.springframework.context.annotation.Lazy; |
| ... | ... | @@ -56,6 +58,10 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { |
| 56 | 58 | @Lazy |
| 57 | 59 | private MesMdItemService itemService; |
| 58 | 60 | @Resource |
| 61 | + @Lazy | |
| 62 | + private MesWmProductSalesLineService productSalesLineService; | |
| 63 | + | |
| 64 | + @Resource | |
| 59 | 65 | private AdminUserApi adminUserApi; |
| 60 | 66 | |
| 61 | 67 | @Override |
| ... | ... | @@ -100,16 +106,47 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { |
| 100 | 106 | } |
| 101 | 107 | |
| 102 | 108 | @Override |
| 109 | + @Transactional(rollbackFor = Exception.class) | |
| 103 | 110 | public void finishOqc(Long id) { |
| 104 | - // 1. 校验存在 + 草稿状态 | |
| 105 | - validateOqcStatusPrepare(id); | |
| 111 | + // 1.1 校验存在 + 草稿状态 | |
| 112 | + MesQcOqcDO oqc = validateOqcStatusPrepare(id); | |
| 113 | + // 1.2 校验检测结论必填 | |
| 114 | + if (oqc.getCheckResult() == null) { | |
| 115 | + throw exception(QC_OQC_CHECK_RESULT_EMPTY); | |
| 116 | + } | |
| 106 | 117 | |
| 107 | 118 | // 2. 更新状态为已完成 |
| 108 | 119 | MesQcOqcDO updateObj = new MesQcOqcDO() |
| 109 | 120 | .setId(id).setStatus(MesQcStatusEnum.FINISHED.getStatus()); |
| 110 | 121 | oqcMapper.updateById(updateObj); |
| 111 | 122 | |
| 112 | - // TODO @芋艿:WM 模块迁移后,更新销售出库单行的检验结果 | |
| 123 | + // 3. 回写来源单据 | |
| 124 | + writeBackSourceDoc(oqc); | |
| 125 | + } | |
| 126 | + | |
| 127 | + /** | |
| 128 | + * 回写来源单据(OQC 完成后) | |
| 129 | + * | |
| 130 | + * <p>当来源为销售出库单时,回写行的 oqcId 和 qualityStatus | |
| 131 | + * | |
| 132 | + * @param oqc 出货检验单 | |
| 133 | + */ | |
| 134 | + private void writeBackSourceDoc(MesQcOqcDO oqc) { | |
| 135 | + if (oqc.getSourceDocType() == null) { | |
| 136 | + return; | |
| 137 | + } | |
| 138 | + if (oqc.getSourceLineId() == null) { | |
| 139 | + throw new IllegalArgumentException( | |
| 140 | + "OQC 单[" + oqc.getId() + "] sourceDocType 非空但 sourceLineId 为空"); | |
| 141 | + } | |
| 142 | + | |
| 143 | + if (Objects.equals(oqc.getSourceDocType(), MesBizTypeConstants.WM_PRODUCT_SALES)) { | |
| 144 | + // 回写销售出库单行的 oqcId + qualityStatus | |
| 145 | + productSalesLineService.updateProductSalesLineWhenOqcFinish(oqc.getSourceLineId(), oqc.getId(), oqc.getCheckResult()); | |
| 146 | + } else { | |
| 147 | + throw new IllegalArgumentException( | |
| 148 | + "OQC 单[" + oqc.getId() + "] sourceDocType=" + oqc.getSourceDocType() + " 无法识别,无法回写来源单据"); | |
| 149 | + } | |
| 113 | 150 | } |
| 114 | 151 | |
| 115 | 152 | @Override |
| ... | ... | @@ -190,8 +227,8 @@ public class MesQcOqcServiceImpl implements MesQcOqcService { |
| 190 | 227 | BigDecimal criticalRate = BigDecimal.ZERO; |
| 191 | 228 | BigDecimal majorRate = BigDecimal.ZERO; |
| 192 | 229 | BigDecimal minorRate = BigDecimal.ZERO; |
| 193 | - if (oqc.getCheckQuantity() != null && oqc.getCheckQuantity() > 0) { | |
| 194 | - BigDecimal checkQty = BigDecimal.valueOf(oqc.getCheckQuantity()); | |
| 230 | + if (oqc.getCheckQuantity() != null && oqc.getCheckQuantity().compareTo(BigDecimal.ZERO) > 0) { | |
| 231 | + BigDecimal checkQty = oqc.getCheckQuantity(); | |
| 195 | 232 | criticalRate = BigDecimal.valueOf(totalCritical).multiply(BigDecimal.valueOf(100)) |
| 196 | 233 | .divide(checkQty, 2, RoundingMode.HALF_UP); |
| 197 | 234 | majorRate = BigDecimal.valueOf(totalMajor).multiply(BigDecimal.valueOf(100)) | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java
| ... | ... | @@ -12,9 +12,12 @@ import cn.iocoder.yudao.module.mes.dal.mysql.qc.rqc.MesQcRqcMapper; |
| 12 | 12 | import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; |
| 13 | 13 | import cn.iocoder.yudao.module.mes.enums.qc.MesQcDefectLevelEnum; |
| 14 | 14 | import cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum; |
| 15 | +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | |
| 15 | 16 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 16 | 17 | import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; |
| 17 | 18 | import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateDetailService; |
| 19 | +import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueLineService; | |
| 20 | +import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesLineService; | |
| 18 | 21 | import cn.iocoder.yudao.module.system.api.user.AdminUserApi; |
| 19 | 22 | import jakarta.annotation.Resource; |
| 20 | 23 | import org.springframework.context.annotation.Lazy; |
| ... | ... | @@ -51,6 +54,12 @@ public class MesQcRqcServiceImpl implements MesQcRqcService { |
| 51 | 54 | @Resource |
| 52 | 55 | @Lazy |
| 53 | 56 | private MesQcDefectRecordService defectRecordService; |
| 57 | + @Resource | |
| 58 | + @Lazy | |
| 59 | + private MesWmReturnIssueLineService returnIssueLineService; | |
| 60 | + @Resource | |
| 61 | + @Lazy | |
| 62 | + private MesWmReturnSalesLineService returnSalesLineService; | |
| 54 | 63 | |
| 55 | 64 | @Resource |
| 56 | 65 | private AdminUserApi adminUserApi; |
| ... | ... | @@ -95,10 +104,15 @@ public class MesQcRqcServiceImpl implements MesQcRqcService { |
| 95 | 104 | } |
| 96 | 105 | |
| 97 | 106 | @Override |
| 107 | + @Transactional(rollbackFor = Exception.class) | |
| 98 | 108 | public void finishRqc(Long id) { |
| 99 | 109 | // 1.1 校验存在 + 草稿状态 |
| 100 | 110 | MesQcRqcDO rqc = validateRqcStatusPrepare(id); |
| 101 | - // 1.2 校验合格品 + 不合格品 = 检测数量 | |
| 111 | + // 1.2 校验检测结论必填 | |
| 112 | + if (rqc.getCheckResult() == null) { | |
| 113 | + throw exception(QC_RQC_CHECK_RESULT_EMPTY); | |
| 114 | + } | |
| 115 | + // 1.3 校验合格品 + 不合格品 = 检测数量 | |
| 102 | 116 | if (rqc.getCheckQuantity() != null && rqc.getCheckQuantity().compareTo(BigDecimal.ZERO) > 0) { |
| 103 | 117 | BigDecimal qualified = rqc.getQualifiedQuantity() != null ? rqc.getQualifiedQuantity() : BigDecimal.ZERO; |
| 104 | 118 | BigDecimal unqualified = rqc.getUnqualifiedQuantity() != null ? rqc.getUnqualifiedQuantity() : BigDecimal.ZERO; |
| ... | ... | @@ -111,7 +125,40 @@ public class MesQcRqcServiceImpl implements MesQcRqcService { |
| 111 | 125 | MesQcRqcDO updateObj = new MesQcRqcDO().setId(id).setStatus(MesQcStatusEnum.FINISHED.getStatus()); |
| 112 | 126 | rqcMapper.updateById(updateObj); |
| 113 | 127 | |
| 114 | - // TODO @芋艿:WM 模块迁移后,更新来源退料/退货单行的质量状态 | |
| 128 | + // 3. 回写来源单据 | |
| 129 | + writeBackSourceDoc(rqc); | |
| 130 | + } | |
| 131 | + | |
| 132 | + /** | |
| 133 | + * 回写来源单据(RQC 完成后) | |
| 134 | + * | |
| 135 | + * <p>根据 sourceDocType 分发: | |
| 136 | + * <ul> | |
| 137 | + * <li>WM_RETURN_ISSUE(生产退料单)→ 回写行的 qualityStatus</li> | |
| 138 | + * <li>WM_RETURN_SALES(销售退货单)→ 回写行的 qualityStatus</li> | |
| 139 | + * </ul> | |
| 140 | + * | |
| 141 | + * @param rqc 退货检验单 | |
| 142 | + */ | |
| 143 | + private void writeBackSourceDoc(MesQcRqcDO rqc) { | |
| 144 | + if (rqc.getSourceDocType() == null) { | |
| 145 | + return; | |
| 146 | + } | |
| 147 | + if (rqc.getSourceLineId() == null) { | |
| 148 | + throw new IllegalArgumentException( | |
| 149 | + "RQC 单[" + rqc.getId() + "] sourceDocType 非空但 sourceLineId 为空"); | |
| 150 | + } | |
| 151 | + | |
| 152 | + if (Objects.equals(rqc.getSourceDocType(), MesBizTypeConstants.WM_RETURN_ISSUE)) { | |
| 153 | + // 回写生产退料单行的 qualityStatus | |
| 154 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish(rqc.getSourceLineId(), rqc.getCheckResult()); | |
| 155 | + } else if (Objects.equals(rqc.getSourceDocType(), MesBizTypeConstants.WM_RETURN_SALES)) { | |
| 156 | + // 回写销售退货单行的 qualityStatus | |
| 157 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish(rqc.getSourceLineId(), rqc.getCheckResult()); | |
| 158 | + } else { | |
| 159 | + throw new IllegalArgumentException( | |
| 160 | + "RQC 单[" + rqc.getId() + "] sourceDocType=" + rqc.getSourceDocType() + " 无法识别,无法回写来源单据"); | |
| 161 | + } | |
| 115 | 162 | } |
| 116 | 163 | |
| 117 | 164 | @Override | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineService.java
| ... | ... | @@ -74,7 +74,7 @@ public interface MesWmArrivalNoticeLineService { |
| 74 | 74 | * @param iqcId IQC 检验单编号 |
| 75 | 75 | * @param qualifiedQuantity 合格数量 |
| 76 | 76 | */ |
| 77 | - void updateByIqcComplete(Long lineId, Long iqcId, BigDecimal qualifiedQuantity); | |
| 77 | + void updateArrivalNoticeLineWhenIqcFinish(Long lineId, Long iqcId, BigDecimal qualifiedQuantity); | |
| 78 | 78 | |
| 79 | 79 | /** |
| 80 | 80 | * 校验到货通知单行存在 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeLineServiceImpl.java
| ... | ... | @@ -63,7 +63,7 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine |
| 63 | 63 | /** |
| 64 | 64 | * 初始化合格品数量: |
| 65 | 65 | * 1. 如果不需要 IQC 检验,则合格品数量直接 = 接收数量; |
| 66 | - * 2. 否则,合格品数量由对应的 IQC 检验单负责更新(见 {@link #updateByIqcComplete}) | |
| 66 | + * 2. 否则,合格品数量由对应的 IQC 检验单负责更新(见 {@link #updateArrivalNoticeLineWhenIqcFinish}) | |
| 67 | 67 | */ |
| 68 | 68 | private void initQualifiedQuantityIfNoIqc(MesWmArrivalNoticeLineDO line) { |
| 69 | 69 | if (BooleanUtil.isFalse(line.getIqcCheckFlag())) { |
| ... | ... | @@ -100,7 +100,7 @@ public class MesWmArrivalNoticeLineServiceImpl implements MesWmArrivalNoticeLine |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | @Override |
| 103 | - public void updateByIqcComplete(Long lineId, Long iqcId, BigDecimal qualifiedQuantity) { | |
| 103 | + public void updateArrivalNoticeLineWhenIqcFinish(Long lineId, Long iqcId, BigDecimal qualifiedQuantity) { | |
| 104 | 104 | // 校验行存在 |
| 105 | 105 | validateArrivalNoticeLineExists(lineId); |
| 106 | 106 | // 更新 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeService.java
| ... | ... | @@ -71,7 +71,7 @@ public interface MesWmArrivalNoticeService { |
| 71 | 71 | * @param iqcId IQC 检验单编号 |
| 72 | 72 | * @param qualifiedQuantity 合格数量 |
| 73 | 73 | */ |
| 74 | - void approveArrivalNoticeWhenIqcComplete(Long id, Long lineId, Long iqcId, BigDecimal qualifiedQuantity); | |
| 74 | + void updateArrivalNoticeWhenIqcFinish(Long id, Long lineId, Long iqcId, BigDecimal qualifiedQuantity); | |
| 75 | 75 | |
| 76 | 76 | /** |
| 77 | 77 | * 完成到货通知单(待入库 → 已完成),内部调用 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
| ... | ... | @@ -96,24 +96,23 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService |
| 96 | 96 | throw exception(WM_ARRIVAL_NOTICE_NO_LINE); |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | - // 2. 检查所有行的 iqcCheckFlag:如果没有需要检验的行,则直接审批通过 | |
| 99 | + // 2. 检查所有行的 iqcCheckFlag:如果有需要检验的行,进入待质检状态 | |
| 100 | 100 | boolean needCheck = CollectionUtils.anyMatch(lines, |
| 101 | 101 | line -> Boolean.TRUE.equals(line.getIqcCheckFlag())); |
| 102 | - // TODO @AI:if return;并且不要取反; | |
| 103 | - if (!needCheck) { | |
| 104 | - // 不需要检验,直接进入待入库 | |
| 105 | - arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() | |
| 106 | - .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus())); | |
| 107 | - } else { | |
| 102 | + if (needCheck) { | |
| 108 | 103 | // 需要检验,进入待质检 |
| 109 | 104 | arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() |
| 110 | 105 | .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus())); |
| 106 | + return; | |
| 111 | 107 | } |
| 108 | + // 不需要检验,直接进入待入库 | |
| 109 | + arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() | |
| 110 | + .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus())); | |
| 112 | 111 | } |
| 113 | 112 | |
| 114 | 113 | @Override |
| 115 | 114 | @Transactional(rollbackFor = Exception.class) |
| 116 | - public void approveArrivalNoticeWhenIqcComplete(Long id, Long lineId, Long iqcId, BigDecimal qualifiedQuantity) { | |
| 115 | + public void updateArrivalNoticeWhenIqcFinish(Long id, Long lineId, Long iqcId, BigDecimal qualifiedQuantity) { | |
| 117 | 116 | // 1.1 校验到货通知单存在 |
| 118 | 117 | MesWmArrivalNoticeDO notice = validateArrivalNoticeExists(id); |
| 119 | 118 | // 1.2 校验状态为待质检 |
| ... | ... | @@ -122,14 +121,14 @@ public class MesWmArrivalNoticeServiceImpl implements MesWmArrivalNoticeService |
| 122 | 121 | } |
| 123 | 122 | |
| 124 | 123 | // 2. 更新到货通知单行:绑定 iqcId + 合格数量 |
| 125 | - arrivalNoticeLineService.updateByIqcComplete(lineId, iqcId, qualifiedQuantity); | |
| 124 | + arrivalNoticeLineService.updateArrivalNoticeLineWhenIqcFinish(lineId, iqcId, qualifiedQuantity); | |
| 126 | 125 | |
| 127 | 126 | // 3.1 判断是否所有需检行都已完成 |
| 128 | 127 | List<MesWmArrivalNoticeLineDO> lines = arrivalNoticeLineService.getArrivalNoticeLineListByNoticeId(id); |
| 129 | 128 | boolean hasUnchecked = CollectionUtils.anyMatch(lines, |
| 130 | 129 | line -> Boolean.TRUE.equals(line.getIqcCheckFlag()) && line.getIqcId() == null); |
| 131 | 130 | if (hasUnchecked) { |
| 132 | - log.info("[updateWhenIqcComplete][到货通知单({}) 还有未完成检验的行,暂不更新状态]", id); | |
| 131 | + log.info("[updateArrivalNoticeWhenIqcFinish][到货通知单({}) 还有未完成检验的行,暂不更新状态]", id); | |
| 133 | 132 | return; |
| 134 | 133 | } |
| 135 | 134 | // 3.2 所有行检验完成,更新主表状态 PENDING_QC → PENDING_RECEIPT | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptService.java
| ... | ... | @@ -88,8 +88,8 @@ public interface MesWmOutsourceReceiptService { |
| 88 | 88 | * @param qualifiedQuantity 合格品数量 |
| 89 | 89 | * @param unqualifiedQuantity 不合格品数量 |
| 90 | 90 | */ |
| 91 | - void approveOutsourceReceiptWhenIqcComplete(Long receiptId, Long lineId, Long iqcId, | |
| 92 | - BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity); | |
| 91 | + void updateOutsourceReceiptWhenIqcFinish(Long receiptId, Long lineId, Long iqcId, | |
| 92 | + BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity); | |
| 93 | 93 | |
| 94 | 94 | /** |
| 95 | 95 | * 校验外协入库单和行存在 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptServiceImpl.java
| ... | ... | @@ -209,8 +209,8 @@ public class MesWmOutsourceReceiptServiceImpl implements MesWmOutsourceReceiptSe |
| 209 | 209 | |
| 210 | 210 | @Override |
| 211 | 211 | @Transactional(rollbackFor = Exception.class) |
| 212 | - public void approveOutsourceReceiptWhenIqcComplete(Long receiptId, Long lineId, Long iqcId, | |
| 213 | - BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity) { | |
| 212 | + public void updateOutsourceReceiptWhenIqcFinish(Long receiptId, Long lineId, Long iqcId, | |
| 213 | + BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity) { | |
| 214 | 214 | // 1.1 校验入库单存在 |
| 215 | 215 | MesWmOutsourceReceiptDO receipt = validateOutsourceReceiptExists(receiptId); |
| 216 | 216 | // 1.2 校验状态为待检验 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineService.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.productsales; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 3 | 4 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLinePageReqVO; |
| 4 | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; |
| ... | ... | @@ -65,7 +66,15 @@ public interface MesWmProductSalesLineService { |
| 65 | 66 | * @param pageReqVO 分页查询 |
| 66 | 67 | * @return 销售出库单行分页 |
| 67 | 68 | */ |
| 68 | - cn.iocoder.yudao.framework.common.pojo.PageResult<MesWmProductSalesLineDO> getProductSalesLinePage( | |
| 69 | - MesWmProductSalesLinePageReqVO pageReqVO); | |
| 69 | + PageResult<MesWmProductSalesLineDO> getProductSalesLinePage(MesWmProductSalesLinePageReqVO pageReqVO); | |
| 70 | + | |
| 71 | + /** | |
| 72 | + * OQC 检验完成后,更新销售出库单行的 OQC 质检状态 | |
| 73 | + * | |
| 74 | + * @param id 行 ID | |
| 75 | + * @param oqcId 质检单 ID | |
| 76 | + * @param checkResult 检验结果 | |
| 77 | + */ | |
| 78 | + void updateProductSalesLineWhenOqcFinish(Long id, Long oqcId, Integer checkResult); | |
| 70 | 79 | |
| 71 | 80 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
| ... | ... | @@ -5,15 +5,16 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesW |
| 5 | 5 | import cn.iocoder.yudao.module.mes.controller.admin.wm.productsales.vo.line.MesWmProductSalesLineSaveReqVO; |
| 6 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; |
| 7 | 7 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper; |
| 8 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 9 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; | |
| 8 | 10 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 9 | 11 | import jakarta.annotation.Resource; |
| 10 | -import org.springframework.context.annotation.Lazy; | |
| 11 | 12 | import org.springframework.stereotype.Service; |
| 12 | 13 | import org.springframework.transaction.annotation.Transactional; |
| 13 | 14 | import org.springframework.validation.annotation.Validated; |
| 14 | 15 | |
| 15 | -import java.math.BigDecimal; | |
| 16 | 16 | import java.util.List; |
| 17 | +import java.util.Objects; | |
| 17 | 18 | |
| 18 | 19 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 19 | 20 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_PRODUCT_SALES_LINE_NOT_EXISTS; |
| ... | ... | @@ -29,14 +30,8 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe |
| 29 | 30 | |
| 30 | 31 | @Resource |
| 31 | 32 | private MesWmProductSalesLineMapper productSalesLineMapper; |
| 32 | - | |
| 33 | - @Resource | |
| 34 | - @Lazy | |
| 35 | - private MesWmProductSalesService productSalesService; | |
| 36 | - | |
| 37 | 33 | @Resource |
| 38 | 34 | private MesWmProductSalesDetailService productSalesDetailService; |
| 39 | - | |
| 40 | 35 | @Resource |
| 41 | 36 | private MesMdItemService itemService; |
| 42 | 37 | |
| ... | ... | @@ -104,4 +99,12 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe |
| 104 | 99 | return line; |
| 105 | 100 | } |
| 106 | 101 | |
| 102 | + @Override | |
| 103 | + public void updateProductSalesLineWhenOqcFinish(Long id, Long oqcId, Integer checkResult) { | |
| 104 | + Integer qualityStatus = Objects.equals(checkResult, MesQcCheckResultEnum.PASS.getType()) | |
| 105 | + ? MesWmQualityStatusEnum.PASS.getStatus() : MesWmQualityStatusEnum.FAIL.getStatus(); | |
| 106 | + productSalesLineMapper.updateById(new MesWmProductSalesLineDO() | |
| 107 | + .setId(id).setOqcId(oqcId).setQualityStatus(qualityStatus)); | |
| 108 | + } | |
| 109 | + | |
| 107 | 110 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java
| ... | ... | @@ -82,4 +82,12 @@ public interface MesWmReturnIssueLineService { |
| 82 | 82 | */ |
| 83 | 83 | void updateReturnIssueQualityStatusByIssueId(Long issueId, Integer issueType); |
| 84 | 84 | |
| 85 | + /** | |
| 86 | + * RQC 检验完成后,更新生产退料单行的质量状态 | |
| 87 | + * | |
| 88 | + * @param id 行 ID | |
| 89 | + * @param checkResult 检验结果 | |
| 90 | + */ | |
| 91 | + void updateReturnIssueLineWhenRqcFinish(Long id, Integer checkResult); | |
| 92 | + | |
| 85 | 93 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
| ... | ... | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWm |
| 8 | 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO; |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO; |
| 10 | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueLineMapper; |
| 11 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 11 | 12 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| 12 | 13 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueTypeEnum; |
| 13 | 14 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| ... | ... | @@ -17,6 +18,7 @@ import org.springframework.stereotype.Service; |
| 17 | 18 | import org.springframework.validation.annotation.Validated; |
| 18 | 19 | |
| 19 | 20 | import java.util.List; |
| 21 | +import java.util.Objects; | |
| 20 | 22 | |
| 21 | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 22 | 24 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WM_RETURN_ISSUE_LINE_NOT_EXISTS; |
| ... | ... | @@ -134,4 +136,11 @@ public class MesWmReturnIssueLineServiceImpl implements MesWmReturnIssueLineServ |
| 134 | 136 | return MesWmQualityStatusEnum.FAIL.getStatus(); // 不合格 |
| 135 | 137 | } |
| 136 | 138 | |
| 139 | + @Override | |
| 140 | + public void updateReturnIssueLineWhenRqcFinish(Long id, Integer checkResult) { | |
| 141 | + Integer qualityStatus = Objects.equals(checkResult, MesQcCheckResultEnum.PASS.getType()) | |
| 142 | + ? MesWmQualityStatusEnum.PASS.getStatus() : MesWmQualityStatusEnum.FAIL.getStatus(); | |
| 143 | + issueLineMapper.updateById(new MesWmReturnIssueLineDO().setId(id).setQualityStatus(qualityStatus)); | |
| 144 | + } | |
| 145 | + | |
| 137 | 146 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineService.java
| ... | ... | @@ -82,6 +82,14 @@ public interface MesWmReturnSalesLineService { |
| 82 | 82 | * @param returnId 退货单ID |
| 83 | 83 | * @param qualityStatus 质量状态 |
| 84 | 84 | */ |
| 85 | - void updateQualityStatusByReturnId(Long returnId, String qualityStatus); | |
| 85 | + void updateQualityStatusByReturnId(Long returnId, Integer qualityStatus); | |
| 86 | + | |
| 87 | + /** | |
| 88 | + * RQC 检验完成后,更新销售退货单行的质量状态 | |
| 89 | + * | |
| 90 | + * @param id 行 ID | |
| 91 | + * @param checkResult 检验结果 | |
| 92 | + */ | |
| 93 | + void updateReturnSalesLineWhenRqcFinish(Long id, Integer checkResult); | |
| 86 | 94 | |
| 87 | 95 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java
| ... | ... | @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWm |
| 7 | 7 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| 8 | 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO; |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesLineMapper; |
| 10 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 11 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; | |
| 10 | 12 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 11 | 13 | import jakarta.annotation.Resource; |
| 12 | 14 | import org.springframework.context.annotation.Lazy; |
| ... | ... | @@ -14,6 +16,7 @@ import org.springframework.stereotype.Service; |
| 14 | 16 | import org.springframework.validation.annotation.Validated; |
| 15 | 17 | |
| 16 | 18 | import java.util.List; |
| 19 | +import java.util.Objects; | |
| 17 | 20 | |
| 18 | 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 19 | 22 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.MD_ITEM_BATCH_REQUIRED; |
| ... | ... | @@ -102,7 +105,7 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ |
| 102 | 105 | } |
| 103 | 106 | |
| 104 | 107 | @Override |
| 105 | - public void updateQualityStatusByReturnId(Long returnId, String qualityStatus) { | |
| 108 | + public void updateQualityStatusByReturnId(Long returnId, Integer qualityStatus) { | |
| 106 | 109 | List<MesWmReturnSalesLineDO> lines = returnSalesLineMapper.selectListByReturnId(returnId); |
| 107 | 110 | for (MesWmReturnSalesLineDO line : lines) { |
| 108 | 111 | returnSalesLineMapper.updateById(new MesWmReturnSalesLineDO() |
| ... | ... | @@ -125,4 +128,12 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ |
| 125 | 128 | } |
| 126 | 129 | } |
| 127 | 130 | |
| 131 | + @Override | |
| 132 | + public void updateReturnSalesLineWhenRqcFinish(Long id, Integer checkResult) { | |
| 133 | + Integer qualityStatus = Objects.equals(checkResult, MesQcCheckResultEnum.PASS.getType()) | |
| 134 | + ? MesWmQualityStatusEnum.PASS.getStatus() | |
| 135 | + : MesWmQualityStatusEnum.FAIL.getStatus(); | |
| 136 | + returnSalesLineMapper.updateById(new MesWmReturnSalesLineDO().setId(id).setQualityStatus(qualityStatus)); | |
| 137 | + } | |
| 138 | + | |
| 128 | 139 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java
| ... | ... | @@ -124,7 +124,7 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService { |
| 124 | 124 | |
| 125 | 125 | // DONE @AI:全部的行设置为待检验状态 |
| 126 | 126 | returnSalesLineService.updateQualityStatusByReturnId(id, |
| 127 | - String.valueOf(MesWmQualityStatusEnum.PENDING.getStatus())); | |
| 127 | + MesWmQualityStatusEnum.PENDING.getStatus()); | |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | 130 | @Override | ... | ... |
yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
| ... | ... | @@ -3,11 +3,12 @@ |
| 3 | 3 | <mapper namespace="cn.iocoder.yudao.module.mes.dal.mysql.qc.pendinginspect.MesQcPendingInspectMapper"> |
| 4 | 4 | |
| 5 | 5 | <!-- |
| 6 | - 待检任务查询(UNION ALL 多来源),目前已实现的来源: | |
| 6 | + 待检任务查询(UNION ALL 多来源),已实现的来源: | |
| 7 | 7 | 1. 到货通知单(IQC):状态=待质检(2),行的 iqc_check_flag=1 且 iqc_id IS NULL |
| 8 | 8 | 2. 外协入库单(IQC/OIQC):状态=待检验(1),行的 iqc_check=1 且 iqc_id IS NULL |
| 9 | - | |
| 10 | - TODO IPQC/OQC/RQC 来源待对应模块就绪后补充 | |
| 9 | + 3. 生产报工(IPQC):状态=待检验(3) | |
| 10 | + 4. 销售出库单(OQC):行的 oqc_check=1 且 oqc_id IS NULL | |
| 11 | + 5. 生产退料单(RQC):状态=待检验(5),行的 qc_flag=1 且 quality_status=0(待检) | |
| 11 | 12 | --> |
| 12 | 13 | <select id="selectQcPendingPage" resultType="cn.iocoder.yudao.module.mes.controller.admin.qc.pendinginspect.vo.MesQcPendingInspectRespVO"> |
| 13 | 14 | SELECT * FROM ( |
| ... | ... | @@ -50,6 +51,64 @@ |
| 50 | 51 | AND rl.iqc_id IS NULL |
| 51 | 52 | AND r.deleted = 0 |
| 52 | 53 | AND rl.deleted = 0 |
| 54 | + | |
| 55 | + UNION ALL | |
| 56 | + | |
| 57 | + <!-- 3. IPQC 来源:生产报工(状态=待检验) --> | |
| 58 | + SELECT | |
| 59 | + f.id AS sourceDocId, | |
| 60 | + ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@PRO_FEEDBACK} AS sourceDocType, | |
| 61 | + f.code AS sourceDocCode, | |
| 62 | + NULL AS sourceLineId, | |
| 63 | + f.feedback_time AS recordTime, | |
| 64 | + ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@IPQC.type} AS qcType, | |
| 65 | + f.item_id AS itemId, | |
| 66 | + f.uncheck_quantity AS quantity, | |
| 67 | + NULL AS vendorId | |
| 68 | + FROM mes_pro_feedback f | |
| 69 | + WHERE f.status = ${@cn.iocoder.yudao.module.mes.enums.pro.MesProFeedbackStatusEnum@UNCHECK.status} | |
| 70 | + AND f.deleted = 0 | |
| 71 | + | |
| 72 | + UNION ALL | |
| 73 | + | |
| 74 | + <!-- 4. OQC 来源:销售出库单行(oqc_check=1 且 oqc_id IS NULL) --> | |
| 75 | + SELECT | |
| 76 | + s.id AS sourceDocId, | |
| 77 | + ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_PRODUCT_SALES} AS sourceDocType, | |
| 78 | + s.code AS sourceDocCode, | |
| 79 | + sl.id AS sourceLineId, | |
| 80 | + s.sales_date AS recordTime, | |
| 81 | + ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@OQC.type} AS qcType, | |
| 82 | + sl.item_id AS itemId, | |
| 83 | + sl.quantity AS quantity, | |
| 84 | + NULL AS vendorId | |
| 85 | + FROM mes_wm_product_sales s | |
| 86 | + JOIN mes_wm_product_sales_line sl ON s.id = sl.sales_id | |
| 87 | + WHERE sl.oqc_check = 1 | |
| 88 | + AND sl.oqc_id IS NULL | |
| 89 | + AND s.deleted = 0 | |
| 90 | + AND sl.deleted = 0 | |
| 91 | + | |
| 92 | + UNION ALL | |
| 93 | + | |
| 94 | + <!-- 5. RQC 来源:生产退料单行(状态=待检验,行的 qc_flag=1 且 quality_status=0) --> | |
| 95 | + SELECT | |
| 96 | + ri.id AS sourceDocId, | |
| 97 | + ${@cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants@WM_RETURN_ISSUE} AS sourceDocType, | |
| 98 | + ri.code AS sourceDocCode, | |
| 99 | + ril.id AS sourceLineId, | |
| 100 | + ri.return_date AS recordTime, | |
| 101 | + ${@cn.iocoder.yudao.module.mes.enums.qc.MesQcTypeEnum@RQC.type} AS qcType, | |
| 102 | + ril.item_id AS itemId, | |
| 103 | + ril.quantity AS quantity, | |
| 104 | + NULL AS vendorId | |
| 105 | + FROM mes_wm_return_issue ri | |
| 106 | + JOIN mes_wm_return_issue_line ril ON ri.id = ril.issue_id | |
| 107 | + WHERE ri.status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum@CONFIRMED.status} | |
| 108 | + AND ril.qc_flag = 1 | |
| 109 | + AND ril.quality_status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum@PENDING.status} | |
| 110 | + AND ri.deleted = 0 | |
| 111 | + AND ril.deleted = 0 | |
| 53 | 112 | ) t |
| 54 | 113 | <where> |
| 55 | 114 | <if test="sourceDocCode != null and sourceDocCode != ''"> | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/pro/feedback/MesProFeedbackServiceImplTest.java
| ... | ... | @@ -56,7 +56,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 56 | 56 | private MesWmProductProduceLineService produceLineService; |
| 57 | 57 | |
| 58 | 58 | @Test |
| 59 | - public void testCompleteFeedbackFromIpqc_success_withUnqualified() { | |
| 59 | + public void testUpdateProFeedbackWhenIpqcFinish_success_withUnqualified() { | |
| 60 | 60 | // 准备数据:插入一条待检验状态的报工单 |
| 61 | 61 | Long taskId = randomLongId(); |
| 62 | 62 | Long workOrderId = randomLongId(); |
| ... | ... | @@ -87,7 +87,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 87 | 87 | BigDecimal materialScrapQty = BigDecimal.valueOf(10); |
| 88 | 88 | BigDecimal otherScrapQty = BigDecimal.valueOf(5); |
| 89 | 89 | |
| 90 | - feedbackService.completeFeedbackFromIpqc(feedback.getId(), | |
| 90 | + feedbackService.updateProFeedbackWhenIpqcFinish(feedback.getId(), | |
| 91 | 91 | qualifiedQty, unqualifiedQty, laborScrapQty, materialScrapQty, otherScrapQty); |
| 92 | 92 | |
| 93 | 93 | // 断言 1:调用了 splitPendingAndFinishProduce |
| ... | ... | @@ -115,7 +115,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 115 | 115 | } |
| 116 | 116 | |
| 117 | 117 | @Test |
| 118 | - public void testCompleteFeedbackFromIpqc_success_allQualified() { | |
| 118 | + public void testUpdateProFeedbackWhenIpqcFinish_success_allQualified() { | |
| 119 | 119 | // 准备数据:全部合格 |
| 120 | 120 | Long taskId = randomLongId(); |
| 121 | 121 | Long workOrderId = randomLongId(); |
| ... | ... | @@ -136,7 +136,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 136 | 136 | .thenReturn(List.of(qualifiedLine)); |
| 137 | 137 | |
| 138 | 138 | // 调用 |
| 139 | - feedbackService.completeFeedbackFromIpqc(feedback.getId(), | |
| 139 | + feedbackService.updateProFeedbackWhenIpqcFinish(feedback.getId(), | |
| 140 | 140 | BigDecimal.valueOf(50), BigDecimal.ZERO, |
| 141 | 141 | BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO); |
| 142 | 142 | |
| ... | ... | @@ -151,17 +151,17 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 151 | 151 | } |
| 152 | 152 | |
| 153 | 153 | @Test |
| 154 | - public void testCompleteFeedbackFromIpqc_feedbackNotExists() { | |
| 154 | + public void testUpdateProFeedbackWhenIpqcFinish_feedbackNotExists() { | |
| 155 | 155 | // 调用不存在的 feedbackId,应该抛异常 |
| 156 | 156 | Long feedbackId = randomLongId(); |
| 157 | 157 | assertThrows(Exception.class, () -> |
| 158 | - feedbackService.completeFeedbackFromIpqc(feedbackId, | |
| 158 | + feedbackService.updateProFeedbackWhenIpqcFinish(feedbackId, | |
| 159 | 159 | BigDecimal.TEN, BigDecimal.ZERO, |
| 160 | 160 | BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO)); |
| 161 | 161 | } |
| 162 | 162 | |
| 163 | 163 | @Test |
| 164 | - public void testCompleteFeedbackFromIpqc_feedbackNotUncheck() { | |
| 164 | + public void testUpdateProFeedbackWhenIpqcFinish_feedbackNotUncheck() { | |
| 165 | 165 | // 准备数据:草稿状态(不是 UNCHECK),应该报错 |
| 166 | 166 | MesProFeedbackDO feedback = randomPojo(MesProFeedbackDO.class, o -> { |
| 167 | 167 | o.setStatus(MesProFeedbackStatusEnum.PREPARE.getStatus()); |
| ... | ... | @@ -170,7 +170,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 170 | 170 | |
| 171 | 171 | // 调用,应该抛异常 |
| 172 | 172 | assertThrows(Exception.class, () -> |
| 173 | - feedbackService.completeFeedbackFromIpqc(feedback.getId(), | |
| 173 | + feedbackService.updateProFeedbackWhenIpqcFinish(feedback.getId(), | |
| 174 | 174 | BigDecimal.TEN, BigDecimal.ZERO, |
| 175 | 175 | BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO)); |
| 176 | 176 | |
| ... | ... | @@ -179,7 +179,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 179 | 179 | } |
| 180 | 180 | |
| 181 | 181 | @Test |
| 182 | - public void testCompleteFeedbackFromIpqc_feedbackAlreadyFinished() { | |
| 182 | + public void testUpdateProFeedbackWhenIpqcFinish_feedbackAlreadyFinished() { | |
| 183 | 183 | // 准备数据:已完成状态,不能再次完成 |
| 184 | 184 | MesProFeedbackDO feedback = randomPojo(MesProFeedbackDO.class, o -> { |
| 185 | 185 | o.setStatus(MesProFeedbackStatusEnum.FINISHED.getStatus()); |
| ... | ... | @@ -188,7 +188,7 @@ public class MesProFeedbackServiceImplTest extends BaseDbUnitTest { |
| 188 | 188 | |
| 189 | 189 | // 调用,应该抛异常 |
| 190 | 190 | assertThrows(Exception.class, () -> |
| 191 | - feedbackService.completeFeedbackFromIpqc(feedback.getId(), | |
| 191 | + feedbackService.updateProFeedbackWhenIpqcFinish(feedback.getId(), | |
| 192 | 192 | BigDecimal.TEN, BigDecimal.ZERO, |
| 193 | 193 | BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO)); |
| 194 | 194 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/ipqc/MesQcIpqcServiceImplTest.java
| ... | ... | @@ -88,7 +88,7 @@ public class MesQcIpqcServiceImplTest extends BaseDbUnitTest { |
| 88 | 88 | |
| 89 | 89 | // 断言 2:调用了 feedbackService.completeFeedbackFromIpqc,传递正确参数 |
| 90 | 90 | // 注意:数量经过 DB 存取后 scale 可能变化(例如 80 → 80.00),所以用 any() 匹配 |
| 91 | - verify(feedbackService).completeFeedbackFromIpqc( | |
| 91 | + verify(feedbackService).updateProFeedbackWhenIpqcFinish( | |
| 92 | 92 | eq(sourceDocId), |
| 93 | 93 | any(BigDecimal.class), |
| 94 | 94 | any(BigDecimal.class), |
| ... | ... | @@ -119,7 +119,7 @@ public class MesQcIpqcServiceImplTest extends BaseDbUnitTest { |
| 119 | 119 | ipqcService.finishIpqc(ipqc.getId()); |
| 120 | 120 | |
| 121 | 121 | // 断言:所有数量参数都是 BigDecimal.ZERO(defaultIfNull 处理) |
| 122 | - verify(feedbackService).completeFeedbackFromIpqc( | |
| 122 | + verify(feedbackService).updateProFeedbackWhenIpqcFinish( | |
| 123 | 123 | eq(sourceDocId), |
| 124 | 124 | eq(BigDecimal.ZERO), |
| 125 | 125 | eq(BigDecimal.ZERO), |
| ... | ... | @@ -148,7 +148,7 @@ public class MesQcIpqcServiceImplTest extends BaseDbUnitTest { |
| 148 | 148 | assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedIpqc.getStatus()); |
| 149 | 149 | |
| 150 | 150 | // 断言 2:不应该调用 feedbackService |
| 151 | - verify(feedbackService, never()).completeFeedbackFromIpqc( | |
| 151 | + verify(feedbackService, never()).updateProFeedbackWhenIpqcFinish( | |
| 152 | 152 | anyLong(), any(), any(), any(), any(), any()); |
| 153 | 153 | } |
| 154 | 154 | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/iqc/MesQcIqcServiceImplTest.java
| ... | ... | @@ -58,7 +58,7 @@ public class MesQcIqcServiceImplTest extends BaseDbUnitTest { |
| 58 | 58 | |
| 59 | 59 | @Test |
| 60 | 60 | public void testFinishIqc_writeBack_arrivalNotice() { |
| 61 | - // mock 数据:插入一条草稿状态的 IQC 单,来源为到货通知单 | |
| 61 | + // 准备数据:插入一条草稿状态的 IQC 单,来源为到货通知单 | |
| 62 | 62 | Long sourceDocId = randomLongId(); |
| 63 | 63 | Long sourceLineId = randomLongId(); |
| 64 | 64 | MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { |
| ... | ... | @@ -79,16 +79,16 @@ public class MesQcIqcServiceImplTest extends BaseDbUnitTest { |
| 79 | 79 | MesQcIqcDO updatedIqc = iqcMapper.selectById(iqc.getId()); |
| 80 | 80 | assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedIqc.getStatus()); |
| 81 | 81 | // 断言:验证回写到货通知单(参数使用 any 避免 BigDecimal 精度问题) |
| 82 | - verify(arrivalNoticeService).approveArrivalNoticeWhenIqcComplete( | |
| 82 | + verify(arrivalNoticeService).updateArrivalNoticeWhenIqcFinish( | |
| 83 | 83 | eq(sourceDocId), eq(sourceLineId), eq(iqc.getId()), any(BigDecimal.class)); |
| 84 | 84 | // 断言:不应该调用外协入库单的回写 |
| 85 | - verify(outsourceReceiptService, never()).approveOutsourceReceiptWhenIqcComplete( | |
| 85 | + verify(outsourceReceiptService, never()).updateOutsourceReceiptWhenIqcFinish( | |
| 86 | 86 | anyLong(), anyLong(), anyLong(), any(), any()); |
| 87 | 87 | } |
| 88 | 88 | |
| 89 | 89 | @Test |
| 90 | 90 | public void testFinishIqc_writeBack_outsourceReceipt() { |
| 91 | - // mock 数据:插入一条草稿状态的 IQC 单,来源为外协入库单 | |
| 91 | + // 准备数据:插入一条草稿状态的 IQC 单,来源为外协入库单 | |
| 92 | 92 | Long sourceDocId = randomLongId(); |
| 93 | 93 | Long sourceLineId = randomLongId(); |
| 94 | 94 | MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { |
| ... | ... | @@ -109,16 +109,16 @@ public class MesQcIqcServiceImplTest extends BaseDbUnitTest { |
| 109 | 109 | MesQcIqcDO updatedIqc = iqcMapper.selectById(iqc.getId()); |
| 110 | 110 | assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedIqc.getStatus()); |
| 111 | 111 | // 断言:验证回写外协入库单(参数使用 any 避免 BigDecimal 精度问题) |
| 112 | - verify(outsourceReceiptService).approveOutsourceReceiptWhenIqcComplete( | |
| 112 | + verify(outsourceReceiptService).updateOutsourceReceiptWhenIqcFinish( | |
| 113 | 113 | eq(sourceDocId), eq(sourceLineId), eq(iqc.getId()), any(BigDecimal.class), any(BigDecimal.class)); |
| 114 | 114 | // 断言:不应该调用到货通知单的回写 |
| 115 | - verify(arrivalNoticeService, never()).approveArrivalNoticeWhenIqcComplete( | |
| 115 | + verify(arrivalNoticeService, never()).updateArrivalNoticeWhenIqcFinish( | |
| 116 | 116 | anyLong(), anyLong(), anyLong(), any()); |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | 119 | @Test |
| 120 | 120 | public void testFinishIqc_writeBack_noSourceDoc() { |
| 121 | - // mock 数据:sourceDocType 为空,不需要回写 | |
| 121 | + // 准备数据:sourceDocType 为空,不需要回写 | |
| 122 | 122 | MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { |
| 123 | 123 | o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); |
| 124 | 124 | o.setCheckResult(1); |
| ... | ... | @@ -135,15 +135,15 @@ public class MesQcIqcServiceImplTest extends BaseDbUnitTest { |
| 135 | 135 | MesQcIqcDO updatedIqc = iqcMapper.selectById(iqc.getId()); |
| 136 | 136 | assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedIqc.getStatus()); |
| 137 | 137 | // 断言:不应该调用任何回写 |
| 138 | - verify(arrivalNoticeService, never()).approveArrivalNoticeWhenIqcComplete( | |
| 138 | + verify(arrivalNoticeService, never()).updateArrivalNoticeWhenIqcFinish( | |
| 139 | 139 | anyLong(), anyLong(), anyLong(), any()); |
| 140 | - verify(outsourceReceiptService, never()).approveOutsourceReceiptWhenIqcComplete( | |
| 140 | + verify(outsourceReceiptService, never()).updateOutsourceReceiptWhenIqcFinish( | |
| 141 | 141 | anyLong(), anyLong(), anyLong(), any(), any()); |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | @Test |
| 145 | 145 | public void testFinishIqc_writeBack_sourceDocTypeDirtyData() { |
| 146 | - // mock 数据:sourceDocType 非空但 sourceLineId 为空,应该抛异常 | |
| 146 | + // 准备数据:sourceDocType 非空但 sourceLineId 为空,应该抛异常 | |
| 147 | 147 | MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { |
| 148 | 148 | o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); |
| 149 | 149 | o.setCheckResult(1); |
| ... | ... | @@ -159,7 +159,7 @@ public class MesQcIqcServiceImplTest extends BaseDbUnitTest { |
| 159 | 159 | |
| 160 | 160 | @Test |
| 161 | 161 | public void testFinishIqc_writeBack_unknownSourceDocType() { |
| 162 | - // mock 数据:sourceDocType 无法识别 | |
| 162 | + // 准备数据:sourceDocType 无法识别 | |
| 163 | 163 | MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { |
| 164 | 164 | o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); |
| 165 | 165 | o.setCheckResult(1); |
| ... | ... | @@ -173,4 +173,31 @@ public class MesQcIqcServiceImplTest extends BaseDbUnitTest { |
| 173 | 173 | assertThrows(IllegalArgumentException.class, () -> iqcService.finishIqc(iqc.getId())); |
| 174 | 174 | } |
| 175 | 175 | |
| 176 | + @Test | |
| 177 | + public void testFinishIqc_checkResultEmpty() { | |
| 178 | + // 准备数据:checkResult 为空,应该报错 | |
| 179 | + MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { | |
| 180 | + o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); | |
| 181 | + o.setCheckResult(null); // 检测结论为空 | |
| 182 | + o.setSourceDocType(null); | |
| 183 | + }); | |
| 184 | + iqcMapper.insert(iqc); | |
| 185 | + | |
| 186 | + // 调用,应该抛异常(检测结论必填) | |
| 187 | + assertThrows(Exception.class, () -> iqcService.finishIqc(iqc.getId())); | |
| 188 | + } | |
| 189 | + | |
| 190 | + @Test | |
| 191 | + public void testFinishIqc_notDraftStatus() { | |
| 192 | + // 准备数据:已完成状态,不能再次完成 | |
| 193 | + MesQcIqcDO iqc = randomPojo(MesQcIqcDO.class, o -> { | |
| 194 | + o.setStatus(MesQcStatusEnum.FINISHED.getStatus()); | |
| 195 | + o.setCheckResult(1); | |
| 196 | + }); | |
| 197 | + iqcMapper.insert(iqc); | |
| 198 | + | |
| 199 | + // 调用,应该抛异常(不是草稿状态) | |
| 200 | + assertThrows(Exception.class, () -> iqcService.finishIqc(iqc.getId())); | |
| 201 | + } | |
| 202 | + | |
| 176 | 203 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/oqc/MesQcOqcServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.qc.oqc; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.oqc.MesQcOqcDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.mysql.qc.oqc.MesQcOqcMapper; | |
| 6 | +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | |
| 7 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; | |
| 8 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 9 | +import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; | |
| 10 | +import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateDetailService; | |
| 11 | +import cn.iocoder.yudao.module.mes.service.wm.productsales.MesWmProductSalesLineService; | |
| 12 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 13 | +import jakarta.annotation.Resource; | |
| 14 | +import org.junit.jupiter.api.Test; | |
| 15 | +import org.springframework.context.annotation.Import; | |
| 16 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; | |
| 17 | + | |
| 18 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 19 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 20 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 21 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_OQC_NOT_EXISTS; | |
| 22 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_OQC_NOT_PREPARE; | |
| 23 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 24 | +import static org.mockito.ArgumentMatchers.eq; | |
| 25 | +import static org.mockito.Mockito.verify; | |
| 26 | + | |
| 27 | +/** | |
| 28 | + * {@link MesQcOqcServiceImpl} 的单元测试类 | |
| 29 | + * | |
| 30 | + * @author 芋道源码 | |
| 31 | + */ | |
| 32 | +@Import(MesQcOqcServiceImpl.class) | |
| 33 | +public class MesQcOqcServiceImplTest extends BaseDbUnitTest { | |
| 34 | + | |
| 35 | + @Resource | |
| 36 | + private MesQcOqcServiceImpl oqcService; | |
| 37 | + | |
| 38 | + @Resource | |
| 39 | + private MesQcOqcMapper oqcMapper; | |
| 40 | + | |
| 41 | + @MockitoBean | |
| 42 | + private MesWmProductSalesLineService productSalesLineService; | |
| 43 | + @MockitoBean | |
| 44 | + private MesQcOqcLineService oqcLineService; | |
| 45 | + @MockitoBean | |
| 46 | + private MesMdItemService itemService; | |
| 47 | + @MockitoBean | |
| 48 | + private MesQcTemplateDetailService templateDetailService; | |
| 49 | + @MockitoBean | |
| 50 | + private MesQcDefectRecordService defectRecordService; | |
| 51 | + @MockitoBean | |
| 52 | + private AdminUserApi adminUserApi; | |
| 53 | + | |
| 54 | + @Test | |
| 55 | + public void testFinishOqc_success() { | |
| 56 | + // 准备参数 | |
| 57 | + Long sourceLineId = randomLongId(); | |
| 58 | + Integer checkResult = 1; | |
| 59 | + | |
| 60 | + // mock 数据 | |
| 61 | + MesQcOqcDO oqc = randomPojo(MesQcOqcDO.class, o -> { | |
| 62 | + o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); | |
| 63 | + o.setSourceDocType(MesBizTypeConstants.WM_PRODUCT_SALES); | |
| 64 | + o.setSourceLineId(sourceLineId); | |
| 65 | + o.setCheckResult(checkResult); | |
| 66 | + }); | |
| 67 | + oqcMapper.insert(oqc); | |
| 68 | + | |
| 69 | + // 调用 | |
| 70 | + oqcService.finishOqc(oqc.getId()); | |
| 71 | + | |
| 72 | + // 断言:验证状态更新 | |
| 73 | + MesQcOqcDO updatedOqc = oqcMapper.selectById(oqc.getId()); | |
| 74 | + assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedOqc.getStatus()); | |
| 75 | + | |
| 76 | + // 断言:验证回写调用 | |
| 77 | + verify(productSalesLineService).updateProductSalesLineWhenOqcFinish(eq(sourceLineId), eq(oqc.getId()), eq(checkResult)); | |
| 78 | + } | |
| 79 | + | |
| 80 | + @Test | |
| 81 | + public void testFinishOqc_notExists() { | |
| 82 | + // 准备参数 | |
| 83 | + Long oqcId = randomLongId(); | |
| 84 | + | |
| 85 | + // 调用,并断言异常 | |
| 86 | + assertServiceException(() -> oqcService.finishOqc(oqcId), QC_OQC_NOT_EXISTS); | |
| 87 | + } | |
| 88 | + | |
| 89 | + @Test | |
| 90 | + public void testFinishOqc_statusNotDraft() { | |
| 91 | + // 准备参数 | |
| 92 | + // mock 数据:状态为已完成 | |
| 93 | + MesQcOqcDO oqc = randomPojo(MesQcOqcDO.class, o -> { | |
| 94 | + o.setStatus(MesQcStatusEnum.FINISHED.getStatus()); | |
| 95 | + }); | |
| 96 | + oqcMapper.insert(oqc); | |
| 97 | + | |
| 98 | + // 调用,并断言异常 | |
| 99 | + assertServiceException(() -> oqcService.finishOqc(oqc.getId()), QC_OQC_NOT_PREPARE); | |
| 100 | + } | |
| 101 | + | |
| 102 | +} | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.qc.rqc; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.mysql.qc.rqc.MesQcRqcMapper; | |
| 6 | +import cn.iocoder.yudao.module.mes.enums.MesBizTypeConstants; | |
| 7 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcStatusEnum; | |
| 8 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 9 | +import cn.iocoder.yudao.module.mes.service.qc.defectrecord.MesQcDefectRecordService; | |
| 10 | +import cn.iocoder.yudao.module.mes.service.qc.template.MesQcTemplateDetailService; | |
| 11 | +import cn.iocoder.yudao.module.mes.service.wm.returnissue.MesWmReturnIssueLineService; | |
| 12 | +import cn.iocoder.yudao.module.mes.service.wm.returnsales.MesWmReturnSalesLineService; | |
| 13 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 14 | +import jakarta.annotation.Resource; | |
| 15 | +import org.junit.jupiter.api.Test; | |
| 16 | +import org.springframework.context.annotation.Import; | |
| 17 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; | |
| 18 | + | |
| 19 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; | |
| 20 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 21 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 22 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_RQC_NOT_EXISTS; | |
| 23 | +import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_RQC_NOT_PREPARE; | |
| 24 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 25 | +import static org.mockito.ArgumentMatchers.anyInt; | |
| 26 | +import static org.mockito.ArgumentMatchers.anyLong; | |
| 27 | +import static org.mockito.ArgumentMatchers.eq; | |
| 28 | +import static org.mockito.Mockito.never; | |
| 29 | +import static org.mockito.Mockito.verify; | |
| 30 | + | |
| 31 | +/** | |
| 32 | + * {@link MesQcRqcServiceImpl} 的单元测试类 | |
| 33 | + * | |
| 34 | + * @author 芋道源码 | |
| 35 | + */ | |
| 36 | +@Import(MesQcRqcServiceImpl.class) | |
| 37 | +public class MesQcRqcServiceImplTest extends BaseDbUnitTest { | |
| 38 | + | |
| 39 | + @Resource | |
| 40 | + private MesQcRqcServiceImpl rqcService; | |
| 41 | + | |
| 42 | + @Resource | |
| 43 | + private MesQcRqcMapper rqcMapper; | |
| 44 | + | |
| 45 | + @MockitoBean | |
| 46 | + private MesWmReturnIssueLineService returnIssueLineService; | |
| 47 | + @MockitoBean | |
| 48 | + private MesWmReturnSalesLineService returnSalesLineService; | |
| 49 | + @MockitoBean | |
| 50 | + private MesQcRqcLineService rqcLineService; | |
| 51 | + @MockitoBean | |
| 52 | + private MesMdItemService itemService; | |
| 53 | + @MockitoBean | |
| 54 | + private MesQcTemplateDetailService templateDetailService; | |
| 55 | + @MockitoBean | |
| 56 | + private MesQcDefectRecordService defectRecordService; | |
| 57 | + @MockitoBean | |
| 58 | + private AdminUserApi adminUserApi; | |
| 59 | + | |
| 60 | + @Test | |
| 61 | + public void testFinishRqc_successWithReturnIssue() { | |
| 62 | + // 准备参数 | |
| 63 | + Long sourceLineId = randomLongId(); | |
| 64 | + Integer checkResult = 1; | |
| 65 | + | |
| 66 | + // mock 数据 | |
| 67 | + MesQcRqcDO rqc = randomPojo(MesQcRqcDO.class, o -> { | |
| 68 | + o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); | |
| 69 | + o.setSourceDocType(MesBizTypeConstants.WM_RETURN_ISSUE); | |
| 70 | + o.setSourceLineId(sourceLineId); | |
| 71 | + o.setCheckResult(checkResult); | |
| 72 | + // 设置数量通过 finishRqc 的数量校验:合格 + 不合格 = 检测数量 | |
| 73 | + o.setCheckQuantity(new java.math.BigDecimal("100")); | |
| 74 | + o.setQualifiedQuantity(new java.math.BigDecimal("80")); | |
| 75 | + o.setUnqualifiedQuantity(new java.math.BigDecimal("20")); | |
| 76 | + }); | |
| 77 | + rqcMapper.insert(rqc); | |
| 78 | + | |
| 79 | + // 调用 | |
| 80 | + rqcService.finishRqc(rqc.getId()); | |
| 81 | + | |
| 82 | + // 断言:验证状态更新 | |
| 83 | + MesQcRqcDO updatedRqc = rqcMapper.selectById(rqc.getId()); | |
| 84 | + assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedRqc.getStatus()); | |
| 85 | + | |
| 86 | + // 断言:验证回写调用生产退料 | |
| 87 | + verify(returnIssueLineService).updateReturnIssueLineWhenRqcFinish(eq(sourceLineId), eq(checkResult)); | |
| 88 | + // 断言:未调用销售退货 | |
| 89 | + verify(returnSalesLineService, never()).updateReturnSalesLineWhenRqcFinish(anyLong(), anyInt()); | |
| 90 | + } | |
| 91 | + | |
| 92 | + @Test | |
| 93 | + public void testFinishRqc_successWithReturnSales() { | |
| 94 | + // 准备参数 | |
| 95 | + Long sourceLineId = randomLongId(); | |
| 96 | + Integer checkResult = 1; | |
| 97 | + | |
| 98 | + // mock 数据 | |
| 99 | + MesQcRqcDO rqc = randomPojo(MesQcRqcDO.class, o -> { | |
| 100 | + o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); | |
| 101 | + o.setSourceDocType(MesBizTypeConstants.WM_RETURN_SALES); | |
| 102 | + o.setSourceLineId(sourceLineId); | |
| 103 | + o.setCheckResult(checkResult); | |
| 104 | + // 设置数量通过 finishRqc 的数量校验:合格 + 不合格 = 检测数量 | |
| 105 | + o.setCheckQuantity(new java.math.BigDecimal("100")); | |
| 106 | + o.setQualifiedQuantity(new java.math.BigDecimal("90")); | |
| 107 | + o.setUnqualifiedQuantity(new java.math.BigDecimal("10")); | |
| 108 | + }); | |
| 109 | + rqcMapper.insert(rqc); | |
| 110 | + | |
| 111 | + // 调用 | |
| 112 | + rqcService.finishRqc(rqc.getId()); | |
| 113 | + | |
| 114 | + // 断言:验证状态更新 | |
| 115 | + MesQcRqcDO updatedRqc = rqcMapper.selectById(rqc.getId()); | |
| 116 | + assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedRqc.getStatus()); | |
| 117 | + | |
| 118 | + // 断言:验证回写调用销售退货 | |
| 119 | + verify(returnSalesLineService).updateReturnSalesLineWhenRqcFinish(eq(sourceLineId), eq(checkResult)); | |
| 120 | + // 断言:未调用生产退料 | |
| 121 | + verify(returnIssueLineService, never()).updateReturnIssueLineWhenRqcFinish(anyLong(), anyInt()); | |
| 122 | + } | |
| 123 | + | |
| 124 | + @Test | |
| 125 | + public void testFinishRqc_notExists() { | |
| 126 | + // 准备参数 | |
| 127 | + Long rqcId = randomLongId(); | |
| 128 | + | |
| 129 | + // 调用,并断言异常 | |
| 130 | + assertServiceException(() -> rqcService.finishRqc(rqcId), QC_RQC_NOT_EXISTS); | |
| 131 | + } | |
| 132 | + | |
| 133 | + @Test | |
| 134 | + public void testFinishRqc_statusNotDraft() { | |
| 135 | + // 准备参数 | |
| 136 | + // mock 数据:状态为已完成 | |
| 137 | + MesQcRqcDO rqc = randomPojo(MesQcRqcDO.class, o -> { | |
| 138 | + o.setStatus(MesQcStatusEnum.FINISHED.getStatus()); | |
| 139 | + }); | |
| 140 | + rqcMapper.insert(rqc); | |
| 141 | + | |
| 142 | + // 调用,并断言异常 | |
| 143 | + assertServiceException(() -> rqcService.finishRqc(rqc.getId()), QC_RQC_NOT_PREPARE); | |
| 144 | + } | |
| 145 | + | |
| 146 | +} | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImplTest.java
| ... | ... | @@ -23,7 +23,7 @@ import static org.mockito.ArgumentMatchers.eq; |
| 23 | 23 | import static org.mockito.Mockito.*; |
| 24 | 24 | |
| 25 | 25 | /** |
| 26 | - * {@link MesWmArrivalNoticeServiceImpl#approveArrivalNoticeWhenIqcComplete} 的单元测试 | |
| 26 | + * {@link MesWmArrivalNoticeServiceImpl} 的单元测试 | |
| 27 | 27 | * |
| 28 | 28 | * @author 芋道源码 |
| 29 | 29 | */ |
| ... | ... | @@ -40,7 +40,7 @@ public class MesWmArrivalNoticeServiceImplTest extends BaseDbUnitTest { |
| 40 | 40 | private MesWmArrivalNoticeLineService arrivalNoticeLineService; |
| 41 | 41 | |
| 42 | 42 | @Test |
| 43 | - public void testApproveArrivalNoticeWhenIqcComplete_success_allLinesChecked() { | |
| 43 | + public void testUpdateArrivalNoticeWhenIqcFinish_success_allLinesChecked() { | |
| 44 | 44 | // mock 数据:插入一条待质检的到货通知单 |
| 45 | 45 | MesWmArrivalNoticeDO notice = randomPojo(MesWmArrivalNoticeDO.class, o -> { |
| 46 | 46 | o.setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus()); |
| ... | ... | @@ -67,17 +67,17 @@ public class MesWmArrivalNoticeServiceImplTest extends BaseDbUnitTest { |
| 67 | 67 | .thenReturn(Arrays.asList(line1, line2)); |
| 68 | 68 | |
| 69 | 69 | // 调用 |
| 70 | - arrivalNoticeService.approveArrivalNoticeWhenIqcComplete(noticeId, lineId, iqcId, qualifiedQuantity); | |
| 70 | + arrivalNoticeService.updateArrivalNoticeWhenIqcFinish(noticeId, lineId, iqcId, qualifiedQuantity); | |
| 71 | 71 | |
| 72 | 72 | // 断言:行回写被调用 |
| 73 | - verify(arrivalNoticeLineService).updateByIqcComplete(eq(lineId), eq(iqcId), eq(qualifiedQuantity)); | |
| 73 | + verify(arrivalNoticeLineService).updateArrivalNoticeLineWhenIqcFinish(eq(lineId), eq(iqcId), eq(qualifiedQuantity)); | |
| 74 | 74 | // 断言:主表状态更新为待入库 |
| 75 | 75 | MesWmArrivalNoticeDO updatedNotice = arrivalNoticeMapper.selectById(noticeId); |
| 76 | 76 | assertEquals(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus(), updatedNotice.getStatus()); |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | 79 | @Test |
| 80 | - public void testApproveArrivalNoticeWhenIqcComplete_success_hasUncheckedLines() { | |
| 80 | + public void testUpdateArrivalNoticeWhenIqcFinish_success_hasUncheckedLines() { | |
| 81 | 81 | // mock 数据:插入一条待质检的到货通知单 |
| 82 | 82 | MesWmArrivalNoticeDO notice = randomPojo(MesWmArrivalNoticeDO.class, o -> { |
| 83 | 83 | o.setStatus(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus()); |
| ... | ... | @@ -104,17 +104,17 @@ public class MesWmArrivalNoticeServiceImplTest extends BaseDbUnitTest { |
| 104 | 104 | .thenReturn(Arrays.asList(line1, line2)); |
| 105 | 105 | |
| 106 | 106 | // 调用 |
| 107 | - arrivalNoticeService.approveArrivalNoticeWhenIqcComplete(noticeId, lineId, iqcId, qualifiedQuantity); | |
| 107 | + arrivalNoticeService.updateArrivalNoticeWhenIqcFinish(noticeId, lineId, iqcId, qualifiedQuantity); | |
| 108 | 108 | |
| 109 | 109 | // 断言:行回写被调用 |
| 110 | - verify(arrivalNoticeLineService).updateByIqcComplete(eq(lineId), eq(iqcId), eq(qualifiedQuantity)); | |
| 110 | + verify(arrivalNoticeLineService).updateArrivalNoticeLineWhenIqcFinish(eq(lineId), eq(iqcId), eq(qualifiedQuantity)); | |
| 111 | 111 | // 断言:主表状态不变,仍然是待质检 |
| 112 | 112 | MesWmArrivalNoticeDO updatedNotice = arrivalNoticeMapper.selectById(noticeId); |
| 113 | 113 | assertEquals(MesWmArrivalNoticeStatusEnum.PENDING_QC.getStatus(), updatedNotice.getStatus()); |
| 114 | 114 | } |
| 115 | 115 | |
| 116 | 116 | @Test |
| 117 | - public void testApproveArrivalNoticeWhenIqcComplete_noticeNotExists() { | |
| 117 | + public void testUpdateArrivalNoticeWhenIqcFinish_noticeNotExists() { | |
| 118 | 118 | // 准备参数 |
| 119 | 119 | Long noticeId = randomLongId(); |
| 120 | 120 | Long lineId = randomLongId(); |
| ... | ... | @@ -123,12 +123,12 @@ public class MesWmArrivalNoticeServiceImplTest extends BaseDbUnitTest { |
| 123 | 123 | |
| 124 | 124 | // 调用,并断言异常 |
| 125 | 125 | assertServiceException( |
| 126 | - () -> arrivalNoticeService.approveArrivalNoticeWhenIqcComplete(noticeId, lineId, iqcId, qualifiedQuantity), | |
| 126 | + () -> arrivalNoticeService.updateArrivalNoticeWhenIqcFinish(noticeId, lineId, iqcId, qualifiedQuantity), | |
| 127 | 127 | WM_ARRIVAL_NOTICE_NOT_EXISTS); |
| 128 | 128 | } |
| 129 | 129 | |
| 130 | 130 | @Test |
| 131 | - public void testApproveArrivalNoticeWhenIqcComplete_statusNotPendingQc() { | |
| 131 | + public void testUpdateArrivalNoticeWhenIqcFinish_statusNotPendingQc() { | |
| 132 | 132 | // mock 数据:插入一条草稿状态的到货通知单(非待质检) |
| 133 | 133 | MesWmArrivalNoticeDO notice = randomPojo(MesWmArrivalNoticeDO.class, o -> { |
| 134 | 134 | o.setStatus(MesWmArrivalNoticeStatusEnum.PREPARE.getStatus()); |
| ... | ... | @@ -142,7 +142,7 @@ public class MesWmArrivalNoticeServiceImplTest extends BaseDbUnitTest { |
| 142 | 142 | |
| 143 | 143 | // 调用,并断言异常 |
| 144 | 144 | assertServiceException( |
| 145 | - () -> arrivalNoticeService.approveArrivalNoticeWhenIqcComplete(noticeId, lineId, iqcId, qualifiedQuantity), | |
| 145 | + () -> arrivalNoticeService.updateArrivalNoticeWhenIqcFinish(noticeId, lineId, iqcId, qualifiedQuantity), | |
| 146 | 146 | WM_ARRIVAL_NOTICE_STATUS_NOT_PENDING_QC); |
| 147 | 147 | } |
| 148 | 148 | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/outsourcereceipt/MesWmOutsourceReceiptServiceImplTest.java
| ... | ... | @@ -26,7 +26,7 @@ import static org.mockito.ArgumentMatchers.*; |
| 26 | 26 | import static org.mockito.Mockito.*; |
| 27 | 27 | |
| 28 | 28 | /** |
| 29 | - * {@link MesWmOutsourceReceiptServiceImpl#approveOutsourceReceiptWhenIqcComplete} 的单元测试 | |
| 29 | + * {@link MesWmOutsourceReceiptServiceImpl} 的单元测试 | |
| 30 | 30 | * |
| 31 | 31 | * @author 芋道源码 |
| 32 | 32 | */ |
| ... | ... | @@ -51,7 +51,7 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 51 | 51 | private MesMdItemService itemService; |
| 52 | 52 | |
| 53 | 53 | @Test |
| 54 | - public void testApproveOutsourceReceiptWhenIqcComplete_success_bothQualifiedAndUnqualified() { | |
| 54 | + public void testUpdateOutsourceReceiptWhenIqcFinish_success_bothQualifiedAndUnqualified() { | |
| 55 | 55 | // mock 数据:插入一条待检验状态的外协入库单 |
| 56 | 56 | MesWmOutsourceReceiptDO receipt = randomPojo(MesWmOutsourceReceiptDO.class, o -> { |
| 57 | 57 | o.setStatus(MesWmOutsourceReceiptStatusEnum.CONFIRMED.getStatus()); |
| ... | ... | @@ -73,7 +73,7 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 73 | 73 | when(outsourceReceiptLineService.getOutsourceReceiptLine(eq(lineId))).thenReturn(line); |
| 74 | 74 | |
| 75 | 75 | // 调用 |
| 76 | - outsourceReceiptService.approveOutsourceReceiptWhenIqcComplete( | |
| 76 | + outsourceReceiptService.updateOutsourceReceiptWhenIqcFinish( | |
| 77 | 77 | receiptId, lineId, iqcId, qualifiedQuantity, unqualifiedQuantity); |
| 78 | 78 | |
| 79 | 79 | // 断言:合格品行更新 |
| ... | ... | @@ -94,7 +94,7 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | @Test |
| 97 | - public void testApproveOutsourceReceiptWhenIqcComplete_success_onlyQualified() { | |
| 97 | + public void testUpdateOutsourceReceiptWhenIqcFinish_success_onlyQualified() { | |
| 98 | 98 | // mock 数据:插入一条待检验状态的外协入库单 |
| 99 | 99 | MesWmOutsourceReceiptDO receipt = randomPojo(MesWmOutsourceReceiptDO.class, o -> { |
| 100 | 100 | o.setStatus(MesWmOutsourceReceiptStatusEnum.CONFIRMED.getStatus()); |
| ... | ... | @@ -115,7 +115,7 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 115 | 115 | when(outsourceReceiptLineService.getOutsourceReceiptLine(eq(lineId))).thenReturn(line); |
| 116 | 116 | |
| 117 | 117 | // 调用 |
| 118 | - outsourceReceiptService.approveOutsourceReceiptWhenIqcComplete( | |
| 118 | + outsourceReceiptService.updateOutsourceReceiptWhenIqcFinish( | |
| 119 | 119 | receiptId, lineId, iqcId, qualifiedQuantity, unqualifiedQuantity); |
| 120 | 120 | |
| 121 | 121 | // 断言:合格品行更新 |
| ... | ... | @@ -129,7 +129,7 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 129 | 129 | } |
| 130 | 130 | |
| 131 | 131 | @Test |
| 132 | - public void testApproveOutsourceReceiptWhenIqcComplete_receiptNotExists() { | |
| 132 | + public void testUpdateOutsourceReceiptWhenIqcFinish_receiptNotExists() { | |
| 133 | 133 | // 准备参数 |
| 134 | 134 | Long receiptId = randomLongId(); |
| 135 | 135 | Long lineId = randomLongId(); |
| ... | ... | @@ -139,13 +139,13 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 139 | 139 | |
| 140 | 140 | // 调用,并断言异常 |
| 141 | 141 | assertServiceException( |
| 142 | - () -> outsourceReceiptService.approveOutsourceReceiptWhenIqcComplete( | |
| 142 | + () -> outsourceReceiptService.updateOutsourceReceiptWhenIqcFinish( | |
| 143 | 143 | receiptId, lineId, iqcId, qualifiedQuantity, unqualifiedQuantity), |
| 144 | 144 | WM_OUTSOURCE_RECEIPT_NOT_EXISTS); |
| 145 | 145 | } |
| 146 | 146 | |
| 147 | 147 | @Test |
| 148 | - public void testApproveOutsourceReceiptWhenIqcComplete_statusNotConfirmed() { | |
| 148 | + public void testUpdateOutsourceReceiptWhenIqcFinish_statusNotConfirmed() { | |
| 149 | 149 | // mock 数据:插入一条草稿状态的外协入库单(非待检验状态) |
| 150 | 150 | MesWmOutsourceReceiptDO receipt = randomPojo(MesWmOutsourceReceiptDO.class, o -> { |
| 151 | 151 | o.setStatus(MesWmOutsourceReceiptStatusEnum.PREPARE.getStatus()); |
| ... | ... | @@ -160,13 +160,13 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 160 | 160 | |
| 161 | 161 | // 调用,并断言异常 |
| 162 | 162 | assertServiceException( |
| 163 | - () -> outsourceReceiptService.approveOutsourceReceiptWhenIqcComplete( | |
| 163 | + () -> outsourceReceiptService.updateOutsourceReceiptWhenIqcFinish( | |
| 164 | 164 | receiptId, lineId, iqcId, qualifiedQuantity, unqualifiedQuantity), |
| 165 | 165 | WM_OUTSOURCE_RECEIPT_STATUS_ERROR); |
| 166 | 166 | } |
| 167 | 167 | |
| 168 | 168 | @Test |
| 169 | - public void testApproveOutsourceReceiptWhenIqcComplete_lineNotExists() { | |
| 169 | + public void testUpdateOutsourceReceiptWhenIqcFinish_lineNotExists() { | |
| 170 | 170 | // mock 数据:插入一条待检验状态的外协入库单 |
| 171 | 171 | MesWmOutsourceReceiptDO receipt = randomPojo(MesWmOutsourceReceiptDO.class, o -> { |
| 172 | 172 | o.setStatus(MesWmOutsourceReceiptStatusEnum.CONFIRMED.getStatus()); |
| ... | ... | @@ -184,7 +184,7 @@ public class MesWmOutsourceReceiptServiceImplTest extends BaseDbUnitTest { |
| 184 | 184 | |
| 185 | 185 | // 调用,并断言异常 |
| 186 | 186 | assertServiceException( |
| 187 | - () -> outsourceReceiptService.approveOutsourceReceiptWhenIqcComplete( | |
| 187 | + () -> outsourceReceiptService.updateOutsourceReceiptWhenIqcFinish( | |
| 188 | 188 | receiptId, lineId, iqcId, qualifiedQuantity, unqualifiedQuantity), |
| 189 | 189 | WM_OUTSOURCE_RECEIPT_LINE_NOT_EXISTS); |
| 190 | 190 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.productsales; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper; | |
| 6 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 7 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; | |
| 8 | +import jakarta.annotation.Resource; | |
| 9 | +import org.junit.jupiter.api.Test; | |
| 10 | +import org.springframework.context.annotation.Import; | |
| 11 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; | |
| 12 | + | |
| 13 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 14 | + | |
| 15 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; | |
| 16 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 17 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 18 | + | |
| 19 | +/** | |
| 20 | + * {@link MesWmProductSalesLineServiceImpl} 的单元测试类 | |
| 21 | + * | |
| 22 | + * @author 芋道源码 | |
| 23 | + */ | |
| 24 | +@Import(MesWmProductSalesLineServiceImpl.class) | |
| 25 | +public class MesWmProductSalesLineServiceImplTest extends BaseDbUnitTest { | |
| 26 | + | |
| 27 | + @Resource | |
| 28 | + private MesWmProductSalesLineServiceImpl productSalesLineService; | |
| 29 | + | |
| 30 | + @Resource | |
| 31 | + private MesWmProductSalesLineMapper productSalesLineMapper; | |
| 32 | + | |
| 33 | + @MockitoBean | |
| 34 | + private MesWmProductSalesService productSalesService; | |
| 35 | + | |
| 36 | + @MockitoBean | |
| 37 | + private MesWmProductSalesDetailService productSalesDetailService; | |
| 38 | + | |
| 39 | + @MockitoBean | |
| 40 | + private MesMdItemService itemService; | |
| 41 | + | |
| 42 | + @Test | |
| 43 | + public void testUpdateProductSalesLineWhenOqcFinish_pass() { | |
| 44 | + // 准备参数 | |
| 45 | + Long oqcId = randomLongId(); | |
| 46 | + Integer checkResult = MesQcCheckResultEnum.PASS.getType(); | |
| 47 | + | |
| 48 | + // mock 数据 | |
| 49 | + MesWmProductSalesLineDO lineDO = randomPojo(MesWmProductSalesLineDO.class); | |
| 50 | + productSalesLineMapper.insert(lineDO); | |
| 51 | + | |
| 52 | + // 调用 | |
| 53 | + productSalesLineService.updateProductSalesLineWhenOqcFinish(lineDO.getId(), oqcId, checkResult); | |
| 54 | + | |
| 55 | + // 断言:验证 mapper 更新参数正确 | |
| 56 | + MesWmProductSalesLineDO updateLine = productSalesLineMapper.selectById(lineDO.getId()); | |
| 57 | + assertEquals(oqcId, updateLine.getOqcId()); | |
| 58 | + assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), updateLine.getQualityStatus()); | |
| 59 | + } | |
| 60 | + | |
| 61 | + @Test | |
| 62 | + public void testUpdateProductSalesLineWhenOqcFinish_fail() { | |
| 63 | + // 准备参数 | |
| 64 | + Long oqcId = randomLongId(); | |
| 65 | + Integer checkResult = MesQcCheckResultEnum.FAIL.getType(); | |
| 66 | + | |
| 67 | + // mock 数据 | |
| 68 | + MesWmProductSalesLineDO lineDO = randomPojo(MesWmProductSalesLineDO.class); | |
| 69 | + productSalesLineMapper.insert(lineDO); | |
| 70 | + | |
| 71 | + // 调用 | |
| 72 | + productSalesLineService.updateProductSalesLineWhenOqcFinish(lineDO.getId(), oqcId, checkResult); | |
| 73 | + | |
| 74 | + // 断言:验证 mapper 更新参数正确 | |
| 75 | + MesWmProductSalesLineDO updateLine = productSalesLineMapper.selectById(lineDO.getId()); | |
| 76 | + assertEquals(oqcId, updateLine.getOqcId()); | |
| 77 | + assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), updateLine.getQualityStatus()); | |
| 78 | + } | |
| 79 | + | |
| 80 | +} | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.returnissue; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueLineMapper; | |
| 6 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 7 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; | |
| 8 | +import jakarta.annotation.Resource; | |
| 9 | +import org.junit.jupiter.api.Test; | |
| 10 | +import org.springframework.context.annotation.Import; | |
| 11 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; | |
| 12 | + | |
| 13 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 14 | + | |
| 15 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 16 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * {@link MesWmReturnIssueLineServiceImpl} 的单元测试类 | |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 22 | + */ | |
| 23 | +@Import(MesWmReturnIssueLineServiceImpl.class) | |
| 24 | +public class MesWmReturnIssueLineServiceImplTest extends BaseDbUnitTest { | |
| 25 | + | |
| 26 | + @Resource | |
| 27 | + private MesWmReturnIssueLineServiceImpl returnIssueLineService; | |
| 28 | + | |
| 29 | + @Resource | |
| 30 | + private MesWmReturnIssueLineMapper returnIssueLineMapper; | |
| 31 | + | |
| 32 | + @MockitoBean | |
| 33 | + private MesWmReturnIssueService issueService; | |
| 34 | + | |
| 35 | + @MockitoBean | |
| 36 | + private MesMdItemService itemService; | |
| 37 | + | |
| 38 | + @Test | |
| 39 | + public void testUpdateReturnIssueLineWhenRqcFinish_pass() { | |
| 40 | + // 准备参数 | |
| 41 | + Integer checkResult = MesQcCheckResultEnum.PASS.getType(); | |
| 42 | + | |
| 43 | + // mock 数据 | |
| 44 | + MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class); | |
| 45 | + returnIssueLineMapper.insert(lineDO); | |
| 46 | + | |
| 47 | + // 调用 | |
| 48 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 49 | + | |
| 50 | + // 断言:验证 mapper 更新参数正确 | |
| 51 | + MesWmReturnIssueLineDO updateLine = returnIssueLineMapper.selectById(lineDO.getId()); | |
| 52 | + assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), updateLine.getQualityStatus()); | |
| 53 | + } | |
| 54 | + | |
| 55 | + @Test | |
| 56 | + public void testUpdateReturnIssueLineWhenRqcFinish_fail() { | |
| 57 | + // 准备参数 | |
| 58 | + Integer checkResult = MesQcCheckResultEnum.FAIL.getType(); | |
| 59 | + | |
| 60 | + // mock 数据 | |
| 61 | + MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class); | |
| 62 | + returnIssueLineMapper.insert(lineDO); | |
| 63 | + | |
| 64 | + // 调用 | |
| 65 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 66 | + | |
| 67 | + // 断言:验证 mapper 更新参数正确 | |
| 68 | + MesWmReturnIssueLineDO updateLine = returnIssueLineMapper.selectById(lineDO.getId()); | |
| 69 | + assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), updateLine.getQualityStatus()); | |
| 70 | + } | |
| 71 | + | |
| 72 | +} | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.mes.service.wm.returnsales; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 4 | +import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO; | |
| 5 | +import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesLineMapper; | |
| 6 | +import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 7 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; | |
| 8 | +import jakarta.annotation.Resource; | |
| 9 | +import org.junit.jupiter.api.Test; | |
| 10 | +import org.springframework.context.annotation.Import; | |
| 11 | +import org.springframework.test.context.bean.override.mockito.MockitoBean; | |
| 12 | + | |
| 13 | +import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; | |
| 14 | + | |
| 15 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 16 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 17 | + | |
| 18 | +/** | |
| 19 | + * {@link MesWmReturnSalesLineServiceImpl} 的单元测试类 | |
| 20 | + * | |
| 21 | + * @author 芋道源码 | |
| 22 | + */ | |
| 23 | +@Import(MesWmReturnSalesLineServiceImpl.class) | |
| 24 | +public class MesWmReturnSalesLineServiceImplTest extends BaseDbUnitTest { | |
| 25 | + | |
| 26 | + @Resource | |
| 27 | + private MesWmReturnSalesLineServiceImpl returnSalesLineService; | |
| 28 | + | |
| 29 | + @Resource | |
| 30 | + private MesWmReturnSalesLineMapper returnSalesLineMapper; | |
| 31 | + | |
| 32 | + @MockitoBean | |
| 33 | + private MesWmReturnSalesService returnSalesService; | |
| 34 | + | |
| 35 | + @MockitoBean | |
| 36 | + private MesMdItemService itemService; | |
| 37 | + | |
| 38 | + @Test | |
| 39 | + public void testUpdateReturnSalesLineWhenRqcFinish_pass() { | |
| 40 | + // 准备参数 | |
| 41 | + Integer checkResult = MesQcCheckResultEnum.PASS.getType(); | |
| 42 | + | |
| 43 | + // mock 数据 | |
| 44 | + MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class); | |
| 45 | + returnSalesLineMapper.insert(lineDO); | |
| 46 | + | |
| 47 | + // 调用 | |
| 48 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 49 | + | |
| 50 | + // 断言:验证 mapper 更新参数正确 | |
| 51 | + MesWmReturnSalesLineDO updateLine = returnSalesLineMapper.selectById(lineDO.getId()); | |
| 52 | + assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), updateLine.getQualityStatus()); | |
| 53 | + } | |
| 54 | + | |
| 55 | + @Test | |
| 56 | + public void testUpdateReturnSalesLineWhenRqcFinish_fail() { | |
| 57 | + // 准备参数 | |
| 58 | + Integer checkResult = MesQcCheckResultEnum.FAIL.getType(); | |
| 59 | + | |
| 60 | + // mock 数据 | |
| 61 | + MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class); | |
| 62 | + returnSalesLineMapper.insert(lineDO); | |
| 63 | + | |
| 64 | + // 调用 | |
| 65 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 66 | + | |
| 67 | + // 断言:验证 mapper 更新参数正确 | |
| 68 | + MesWmReturnSalesLineDO updateLine = returnSalesLineMapper.selectById(lineDO.getId()); | |
| 69 | + assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), updateLine.getQualityStatus()); | |
| 70 | + } | |
| 71 | + | |
| 72 | +} | ... | ... |
yudao-module-mes/src/test/resources/sql/create_tables.sql
| ... | ... | @@ -297,3 +297,151 @@ CREATE TABLE IF NOT EXISTS "mes_wm_product_produce_detail" ( |
| 297 | 297 | "tenant_id" bigint NOT NULL DEFAULT 0, |
| 298 | 298 | PRIMARY KEY ("id") |
| 299 | 299 | ); |
| 300 | + | |
| 301 | + | |
| 302 | +-- ---------------------------- | |
| 303 | +-- MES 出货检验单(OQC) | |
| 304 | +-- ---------------------------- | |
| 305 | +CREATE TABLE IF NOT EXISTS "mes_qc_oqc" ( | |
| 306 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 307 | + "code" varchar(64) NOT NULL, | |
| 308 | + "name" varchar(500) NOT NULL, | |
| 309 | + "template_id" bigint NOT NULL, | |
| 310 | + "source_doc_id" bigint DEFAULT NULL, | |
| 311 | + "source_doc_type" int DEFAULT NULL, | |
| 312 | + "source_doc_code" varchar(64) DEFAULT NULL, | |
| 313 | + "source_line_id" bigint DEFAULT NULL, | |
| 314 | + "client_id" bigint NOT NULL, | |
| 315 | + "batch_code" varchar(64) DEFAULT NULL, | |
| 316 | + "item_id" bigint NOT NULL, | |
| 317 | + "min_check_quantity" int DEFAULT 1, | |
| 318 | + "max_unqualified_quantity" int DEFAULT 0, | |
| 319 | + "out_quantity" decimal(14,2) NOT NULL, | |
| 320 | + "check_quantity" decimal(14,2) DEFAULT NULL, | |
| 321 | + "qualified_quantity" decimal(14,2) DEFAULT 0.00, | |
| 322 | + "unqualified_quantity" decimal(14,2) DEFAULT 0.00, | |
| 323 | + "critical_rate" decimal(14,2) DEFAULT 0.00, | |
| 324 | + "major_rate" decimal(14,2) DEFAULT 0.00, | |
| 325 | + "minor_rate" decimal(14,2) DEFAULT 0.00, | |
| 326 | + "critical_quantity" int DEFAULT 0, | |
| 327 | + "major_quantity" int DEFAULT 0, | |
| 328 | + "minor_quantity" int DEFAULT 0, | |
| 329 | + "check_result" tinyint DEFAULT NULL, | |
| 330 | + "out_date" timestamp DEFAULT NULL, | |
| 331 | + "inspect_date" timestamp DEFAULT NULL, | |
| 332 | + "inspector_user_id" bigint DEFAULT NULL, | |
| 333 | + "status" tinyint NOT NULL DEFAULT 0, | |
| 334 | + "remark" varchar(500) DEFAULT '', | |
| 335 | + "creator" varchar(64) DEFAULT '', | |
| 336 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 337 | + "updater" varchar(64) DEFAULT '', | |
| 338 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 339 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 340 | + "tenant_id" bigint NOT NULL DEFAULT 0, | |
| 341 | + PRIMARY KEY ("id") | |
| 342 | +); | |
| 343 | + | |
| 344 | +-- ---------------------------- | |
| 345 | +-- MES 退货检验单(RQC) | |
| 346 | +-- ---------------------------- | |
| 347 | +CREATE TABLE IF NOT EXISTS "mes_qc_rqc" ( | |
| 348 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 349 | + "code" varchar(64) NOT NULL, | |
| 350 | + "name" varchar(500) NOT NULL, | |
| 351 | + "template_id" bigint NOT NULL, | |
| 352 | + "source_doc_id" bigint DEFAULT NULL, | |
| 353 | + "source_doc_type" int DEFAULT NULL, | |
| 354 | + "source_doc_code" varchar(64) DEFAULT NULL, | |
| 355 | + "source_line_id" bigint DEFAULT NULL, | |
| 356 | + "type" int DEFAULT NULL, | |
| 357 | + "item_id" bigint NOT NULL, | |
| 358 | + "batch_code" varchar(128) DEFAULT NULL, | |
| 359 | + "check_quantity" decimal(14,2) DEFAULT NULL, | |
| 360 | + "qualified_quantity" decimal(14,2) DEFAULT 0.00, | |
| 361 | + "unqualified_quantity" decimal(14,2) DEFAULT 0.00, | |
| 362 | + "check_result" tinyint DEFAULT NULL, | |
| 363 | + "inspect_date" timestamp DEFAULT NULL, | |
| 364 | + "inspector_user_id" bigint DEFAULT NULL, | |
| 365 | + "status" tinyint NOT NULL DEFAULT 0, | |
| 366 | + "remark" varchar(500) DEFAULT '', | |
| 367 | + "critical_quantity" int DEFAULT 0, | |
| 368 | + "major_quantity" int DEFAULT 0, | |
| 369 | + "minor_quantity" int DEFAULT 0, | |
| 370 | + "critical_rate" decimal(5,2) DEFAULT 0.00, | |
| 371 | + "major_rate" decimal(5,2) DEFAULT 0.00, | |
| 372 | + "minor_rate" decimal(5,2) DEFAULT 0.00, | |
| 373 | + "creator" varchar(64) DEFAULT '', | |
| 374 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 375 | + "updater" varchar(64) DEFAULT '', | |
| 376 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 377 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 378 | + "tenant_id" bigint NOT NULL DEFAULT 0, | |
| 379 | + PRIMARY KEY ("id") | |
| 380 | +); | |
| 381 | + | |
| 382 | +-- ---------------------------- | |
| 383 | +-- MES 销售出库单行 | |
| 384 | +-- ---------------------------- | |
| 385 | +CREATE TABLE IF NOT EXISTS "mes_wm_product_sales_line" ( | |
| 386 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 387 | + "sales_id" bigint NOT NULL, | |
| 388 | + "item_id" bigint NOT NULL, | |
| 389 | + "quantity" decimal(20,6) NOT NULL, | |
| 390 | + "batch_id" bigint DEFAULT NULL, | |
| 391 | + "material_stock_id" bigint DEFAULT NULL, | |
| 392 | + "oqc_check" tinyint DEFAULT NULL, | |
| 393 | + "oqc_id" bigint DEFAULT NULL, | |
| 394 | + "quality_status" int DEFAULT NULL, | |
| 395 | + "remark" varchar(500) DEFAULT NULL, | |
| 396 | + "creator" varchar(64) DEFAULT '', | |
| 397 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 398 | + "updater" varchar(64) DEFAULT '', | |
| 399 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 400 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 401 | + "tenant_id" bigint NOT NULL DEFAULT 0, | |
| 402 | + PRIMARY KEY ("id") | |
| 403 | +); | |
| 404 | + | |
| 405 | +-- ---------------------------- | |
| 406 | +-- MES 生产退料单行 | |
| 407 | +-- ---------------------------- | |
| 408 | +CREATE TABLE IF NOT EXISTS "mes_wm_return_issue_line" ( | |
| 409 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 410 | + "issue_id" bigint NOT NULL, | |
| 411 | + "material_stock_id" bigint DEFAULT NULL, | |
| 412 | + "item_id" bigint NOT NULL, | |
| 413 | + "quantity" decimal(12,2) NOT NULL DEFAULT 0.00, | |
| 414 | + "batch_id" bigint DEFAULT NULL, | |
| 415 | + "ipqc_id" bigint DEFAULT NULL, | |
| 416 | + "qc_flag" bit NOT NULL DEFAULT FALSE, | |
| 417 | + "quality_status" int DEFAULT NULL, | |
| 418 | + "remark" varchar(500) DEFAULT '', | |
| 419 | + "creator" varchar(64) DEFAULT '', | |
| 420 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 421 | + "updater" varchar(64) DEFAULT '', | |
| 422 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 423 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 424 | + "tenant_id" bigint NOT NULL DEFAULT 0, | |
| 425 | + PRIMARY KEY ("id") | |
| 426 | +); | |
| 427 | + | |
| 428 | +-- ---------------------------- | |
| 429 | +-- MES 销售退货单行 | |
| 430 | +-- ---------------------------- | |
| 431 | +CREATE TABLE IF NOT EXISTS "mes_wm_return_sales_line" ( | |
| 432 | + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, | |
| 433 | + "return_id" bigint NOT NULL, | |
| 434 | + "item_id" bigint NOT NULL, | |
| 435 | + "quantity" decimal(12,2) NOT NULL DEFAULT 0.00, | |
| 436 | + "batch_id" bigint DEFAULT NULL, | |
| 437 | + "quality_status" int DEFAULT NULL, | |
| 438 | + "remark" varchar(500) DEFAULT '', | |
| 439 | + "creator" varchar(64) DEFAULT '', | |
| 440 | + "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 441 | + "updater" varchar(64) DEFAULT '', | |
| 442 | + "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, | |
| 443 | + "deleted" bit NOT NULL DEFAULT FALSE, | |
| 444 | + "tenant_id" bigint NOT NULL DEFAULT 0, | |
| 445 | + PRIMARY KEY ("id") | |
| 446 | +); | |
| 447 | + | ... | ... |