Commit d2feaae7d48c3526ba74cab619f95d9c77a3ce5b
1 parent
40a6786a
✨ feat(mes): 更新退货检验单逻辑,支持合格/不合格数量拆分
优化退货检验单的处理逻辑,新增对合格品和不合格品数量的支持。实现了根据检验结果更新退货单行的质量状态,并在部分合格的情况下进行行拆分。同时,更新了相关的接口和数据结构,确保数据一致性和完整性。
Showing
15 changed files
with
304 additions
and
69 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/MesQcRqcLineController.java
| ... | ... | @@ -9,11 +9,9 @@ import cn.iocoder.yudao.module.mes.controller.admin.qc.rqc.vo.line.MesQcRqcLineR |
| 9 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.unitmeasure.MesMdUnitMeasureDO; |
| 10 | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.rqc.MesQcRqcLineDO; |
| 11 | 11 | import cn.iocoder.yudao.module.mes.dal.dataobject.qc.indicator.MesQcIndicatorDO; |
| 12 | -import cn.iocoder.yudao.module.mes.dal.dataobject.tm.tool.MesTmToolDO; | |
| 13 | 12 | import cn.iocoder.yudao.module.mes.service.md.unitmeasure.MesMdUnitMeasureService; |
| 14 | 13 | import cn.iocoder.yudao.module.mes.service.qc.rqc.MesQcRqcLineService; |
| 15 | 14 | import cn.iocoder.yudao.module.mes.service.qc.indicator.MesQcIndicatorService; |
| 16 | -import cn.iocoder.yudao.module.mes.service.tm.tool.MesTmToolService; | |
| 17 | 15 | import io.swagger.v3.oas.annotations.Operation; |
| 18 | 16 | import io.swagger.v3.oas.annotations.Parameter; |
| 19 | 17 | import io.swagger.v3.oas.annotations.tags.Tag; |
| ... | ... | @@ -46,8 +44,6 @@ public class MesQcRqcLineController { |
| 46 | 44 | private MesQcIndicatorService indicatorService; |
| 47 | 45 | @Resource |
| 48 | 46 | private MesMdUnitMeasureService unitMeasureService; |
| 49 | - @Resource | |
| 50 | - private MesTmToolService toolService; | |
| 51 | 47 | |
| 52 | 48 | @GetMapping("/get") |
| 53 | 49 | @Operation(summary = "获得退货检验单行") | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/controller/admin/qc/rqc/vo/MesQcRqcPageReqVO.java
| ... | ... | @@ -20,8 +20,8 @@ public class MesQcRqcPageReqVO extends PageParam { |
| 20 | 20 | @Schema(description = "检验单编号", example = "RQC2025") |
| 21 | 21 | private String code; |
| 22 | 22 | |
| 23 | - @Schema(description = "来源单据类型", example = "RTISSUE") | |
| 24 | - private String sourceDocType; | |
| 23 | + @Schema(description = "来源单据类型", example = "1") | |
| 24 | + private Integer sourceDocType; | |
| 25 | 25 | |
| 26 | 26 | @Schema(description = "产品物料 ID", example = "20") |
| 27 | 27 | private Long itemId; | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/md/autocode/MesMdAutoCodeRuleCodeEnum.java
| ... | ... | @@ -17,7 +17,8 @@ public enum MesMdAutoCodeRuleCodeEnum { |
| 17 | 17 | BATCH_CODE("WM_BATCH_CODE", "批次编码"), |
| 18 | 18 | TASK_CODE("PRO_TASK_CODE", "生产任务编码"), |
| 19 | 19 | QC_IQC_CODE("QC_IQC_CODE", "来料检验单编码"), |
| 20 | - QC_IPQC_CODE("QC_IPQC_CODE", "过程检验单编码"); | |
| 20 | + QC_IPQC_CODE("QC_IPQC_CODE", "过程检验单编码"), | |
| 21 | + QC_RQC_CODE("QC_RQC_CODE", "退货检验单编码"); | |
| 21 | 22 | |
| 22 | 23 | /** |
| 23 | 24 | * 规则代码 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImpl.java
| ... | ... | @@ -134,8 +134,8 @@ public class MesQcRqcServiceImpl implements MesQcRqcService { |
| 134 | 134 | * |
| 135 | 135 | * <p>根据 sourceDocType 分发: |
| 136 | 136 | * <ul> |
| 137 | - * <li>WM_RETURN_ISSUE(生产退料单)→ 回写行的 qualityStatus</li> | |
| 138 | - * <li>WM_RETURN_SALES(销售退货单)→ 回写行的 qualityStatus</li> | |
| 137 | + * <li>WM_RETURN_ISSUE(生产退料单)→ 根据合格/不合格数量拆分行 + 更新 qualityStatus + 联动主单状态</li> | |
| 138 | + * <li>WM_RETURN_SALES(销售退货单)→ 同上</li> | |
| 139 | 139 | * </ul> |
| 140 | 140 | * |
| 141 | 141 | * @param rqc 退货检验单 |
| ... | ... | @@ -150,11 +150,15 @@ public class MesQcRqcServiceImpl implements MesQcRqcService { |
| 150 | 150 | } |
| 151 | 151 | |
| 152 | 152 | if (Objects.equals(rqc.getSourceDocType(), MesBizTypeConstants.WM_RETURN_ISSUE)) { |
| 153 | - // 回写生产退料单行的 qualityStatus | |
| 154 | - returnIssueLineService.updateReturnIssueLineWhenRqcFinish(rqc.getSourceLineId(), rqc.getCheckResult()); | |
| 153 | + // 回写生产退料单行:拆分行 + 更新质量状态 + 联动主单状态 | |
| 154 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish( | |
| 155 | + rqc.getSourceLineId(), rqc.getSourceDocId(), rqc.getCheckResult(), | |
| 156 | + rqc.getQualifiedQuantity(), rqc.getUnqualifiedQuantity()); | |
| 155 | 157 | } else if (Objects.equals(rqc.getSourceDocType(), MesBizTypeConstants.WM_RETURN_SALES)) { |
| 156 | - // 回写销售退货单行的 qualityStatus | |
| 157 | - returnSalesLineService.updateReturnSalesLineWhenRqcFinish(rqc.getSourceLineId(), rqc.getCheckResult()); | |
| 158 | + // 回写销售退货单行:拆分行 + 更新质量状态 + 联动主单状态 | |
| 159 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish( | |
| 160 | + rqc.getSourceLineId(), rqc.getSourceDocId(), rqc.getCheckResult(), | |
| 161 | + rqc.getQualifiedQuantity(), rqc.getUnqualifiedQuantity()); | |
| 158 | 162 | } else { |
| 159 | 163 | throw new IllegalArgumentException( |
| 160 | 164 | "RQC 单[" + rqc.getId() + "] sourceDocType=" + rqc.getSourceDocType() + " 无法识别,无法回写来源单据"); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineService.java
| ... | ... | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWm |
| 6 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO; |
| 7 | 7 | import jakarta.validation.Valid; |
| 8 | 8 | |
| 9 | +import java.math.BigDecimal; | |
| 9 | 10 | import java.util.List; |
| 10 | 11 | |
| 11 | 12 | /** |
| ... | ... | @@ -83,11 +84,23 @@ public interface MesWmReturnIssueLineService { |
| 83 | 84 | void updateReturnIssueQualityStatusByIssueId(Long issueId, Integer issueType); |
| 84 | 85 | |
| 85 | 86 | /** |
| 86 | - * RQC 检验完成后,更新生产退料单行的质量状态 | |
| 87 | + * RQC 检验完成后,根据合格品/不合格品数量更新生产退料单行 | |
| 87 | 88 | * |
| 88 | - * @param id 行 ID | |
| 89 | - * @param checkResult 检验结果 | |
| 89 | + * <p>拆分逻辑: | |
| 90 | + * <ul> | |
| 91 | + * <li>全部合格:直接更新行的 qualityStatus 为合格</li> | |
| 92 | + * <li>全部不合格:直接更新行的 qualityStatus 为不合格</li> | |
| 93 | + * <li>部分合格部分不合格:拆分原行(原行改为合格+数量=合格数,新增一行不合格+数量=不合格数)</li> | |
| 94 | + * </ul> | |
| 95 | + * 同时检查退料单下所有行是否都已检验完毕,若全检完则将退料单状态设为待上架。 | |
| 96 | + * | |
| 97 | + * @param sourceLineId 来源行 ID | |
| 98 | + * @param sourceDocId 来源退料单 ID | |
| 99 | + * @param checkResult 检验结果 | |
| 100 | + * @param qualifiedQuantity 合格品数量 | |
| 101 | + * @param unqualifiedQuantity 不合格品数量 | |
| 90 | 102 | */ |
| 91 | - void updateReturnIssueLineWhenRqcFinish(Long id, Integer checkResult); | |
| 103 | + void updateReturnIssueLineWhenRqcFinish(Long sourceLineId, Long sourceDocId, Integer checkResult, | |
| 104 | + BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity); | |
| 92 | 105 | |
| 93 | 106 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.returnissue; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.hutool.core.util.ObjUtil; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | 6 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| ... | ... | @@ -8,8 +9,8 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWm |
| 8 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO; |
| 9 | 10 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO; |
| 10 | 11 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueLineMapper; |
| 11 | -import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 12 | 12 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| 13 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum; | |
| 13 | 14 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueTypeEnum; |
| 14 | 15 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 15 | 16 | import jakarta.annotation.Resource; |
| ... | ... | @@ -17,6 +18,7 @@ import org.springframework.context.annotation.Lazy; |
| 17 | 18 | import org.springframework.stereotype.Service; |
| 18 | 19 | import org.springframework.validation.annotation.Validated; |
| 19 | 20 | |
| 21 | +import java.math.BigDecimal; | |
| 20 | 22 | import java.util.List; |
| 21 | 23 | import java.util.Objects; |
| 22 | 24 | |
| ... | ... | @@ -137,10 +139,51 @@ public class MesWmReturnIssueLineServiceImpl implements MesWmReturnIssueLineServ |
| 137 | 139 | } |
| 138 | 140 | |
| 139 | 141 | @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)); | |
| 142 | + public void updateReturnIssueLineWhenRqcFinish(Long sourceLineId, Long sourceDocId, Integer checkResult, | |
| 143 | + BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity) { | |
| 144 | + MesWmReturnIssueLineDO sourceLine = validateReturnIssueLineExists(sourceLineId); | |
| 145 | + boolean hasUnqualified = unqualifiedQuantity != null && unqualifiedQuantity.compareTo(BigDecimal.ZERO) > 0; | |
| 146 | + boolean hasQualified = qualifiedQuantity != null && qualifiedQuantity.compareTo(BigDecimal.ZERO) > 0; | |
| 147 | + | |
| 148 | + // 1. 根据合格/不合格品数量,更新退料单行的质量状态 | |
| 149 | + if (!hasUnqualified) { | |
| 150 | + // 1.A 情况一:全部合格 | |
| 151 | + issueLineMapper.updateById(new MesWmReturnIssueLineDO() | |
| 152 | + .setId(sourceLineId).setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus())); | |
| 153 | + } else if (!hasQualified) { | |
| 154 | + // 1.B 情况二:全部不合格 | |
| 155 | + issueLineMapper.updateById(new MesWmReturnIssueLineDO() | |
| 156 | + .setId(sourceLineId).setQualityStatus(MesWmQualityStatusEnum.FAIL.getStatus())); | |
| 157 | + } else { | |
| 158 | + // 1.C 情况三:部分合格部分不合格 → 拆分行 | |
| 159 | + // 1.C.1 新增一行不合格品 | |
| 160 | + MesWmReturnIssueLineDO unqualifiedLine = new MesWmReturnIssueLineDO() | |
| 161 | + .setIssueId(sourceLine.getIssueId()) | |
| 162 | + .setMaterialStockId(sourceLine.getMaterialStockId()) | |
| 163 | + .setItemId(sourceLine.getItemId()) | |
| 164 | + .setQuantity(unqualifiedQuantity) | |
| 165 | + .setBatchId(sourceLine.getBatchId()) | |
| 166 | + .setIpqcId(sourceLine.getIpqcId()) | |
| 167 | + .setQcFlag(sourceLine.getQcFlag()) | |
| 168 | + .setQualityStatus(MesWmQualityStatusEnum.FAIL.getStatus()) | |
| 169 | + .setRemark(sourceLine.getRemark()); | |
| 170 | + issueLineMapper.insert(unqualifiedLine); | |
| 171 | + // 1.C.2 更新原行为合格品(数量调整为合格数量) | |
| 172 | + issueLineMapper.updateById(new MesWmReturnIssueLineDO() | |
| 173 | + .setId(sourceLineId) | |
| 174 | + .setQuantity(qualifiedQuantity) | |
| 175 | + .setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus())); | |
| 176 | + } | |
| 177 | + | |
| 178 | + // 2. 检查退料单下是否还有待检验的行,若全检完则将退料单状态设为"待上架" | |
| 179 | + if (sourceDocId != null) { | |
| 180 | + List<MesWmReturnIssueLineDO> allLines = issueLineMapper.selectListByIssueId(sourceDocId); | |
| 181 | + boolean allInspected = !CollUtil.contains(allLines, | |
| 182 | + line -> Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.PENDING.getStatus())); | |
| 183 | + if (allInspected) { | |
| 184 | + issueService.updateReturnIssueStatus(sourceDocId, MesWmReturnIssueStatusEnum.APPROVING.getStatus()); | |
| 185 | + } | |
| 186 | + } | |
| 144 | 187 | } |
| 145 | 188 | |
| 146 | 189 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueService.java
| ... | ... | @@ -85,4 +85,12 @@ public interface MesWmReturnIssueService { |
| 85 | 85 | */ |
| 86 | 86 | void cancelReturnIssue(Long id); |
| 87 | 87 | |
| 88 | + /** | |
| 89 | + * 更新生产退料单状态(供外部模块联动调用,如 RQC 检验完成后) | |
| 90 | + * | |
| 91 | + * @param id 编号 | |
| 92 | + * @param status 目标状态 | |
| 93 | + */ | |
| 94 | + void updateReturnIssueStatus(Long id, Integer status); | |
| 95 | + | |
| 88 | 96 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueServiceImpl.java
| ... | ... | @@ -271,4 +271,10 @@ public class MesWmReturnIssueServiceImpl implements MesWmReturnIssueService { |
| 271 | 271 | return issue; |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | + @Override | |
| 275 | + public void updateReturnIssueStatus(Long id, Integer status) { | |
| 276 | + validateReturnIssueExists(id); | |
| 277 | + issueMapper.updateById(new MesWmReturnIssueDO().setId(id).setStatus(status)); | |
| 278 | + } | |
| 279 | + | |
| 274 | 280 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineService.java
| ... | ... | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWm |
| 6 | 6 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO; |
| 7 | 7 | import jakarta.validation.Valid; |
| 8 | 8 | |
| 9 | +import java.math.BigDecimal; | |
| 9 | 10 | import java.util.List; |
| 10 | 11 | |
| 11 | 12 | /** |
| ... | ... | @@ -85,11 +86,23 @@ public interface MesWmReturnSalesLineService { |
| 85 | 86 | void updateQualityStatusByReturnId(Long returnId, Integer qualityStatus); |
| 86 | 87 | |
| 87 | 88 | /** |
| 88 | - * RQC 检验完成后,更新销售退货单行的质量状态 | |
| 89 | + * RQC 检验完成后,根据合格品/不合格品数量更新销售退货单行 | |
| 89 | 90 | * |
| 90 | - * @param id 行 ID | |
| 91 | - * @param checkResult 检验结果 | |
| 91 | + * <p>拆分逻辑: | |
| 92 | + * <ul> | |
| 93 | + * <li>全部合格:直接更新行的 qualityStatus 为合格</li> | |
| 94 | + * <li>全部不合格:直接更新行的 qualityStatus 为不合格</li> | |
| 95 | + * <li>部分合格部分不合格:拆分原行(原行改为合格+数量=合格数,新增一行不合格+数量=不合格数)</li> | |
| 96 | + * </ul> | |
| 97 | + * 同时检查退货单下所有行是否都已检验完毕,若全检完则将退货单状态设为待上架。 | |
| 98 | + * | |
| 99 | + * @param sourceLineId 来源行 ID | |
| 100 | + * @param sourceDocId 来源退货单 ID | |
| 101 | + * @param checkResult 检验结果 | |
| 102 | + * @param qualifiedQuantity 合格品数量 | |
| 103 | + * @param unqualifiedQuantity 不合格品数量 | |
| 92 | 104 | */ |
| 93 | - void updateReturnSalesLineWhenRqcFinish(Long id, Integer checkResult); | |
| 105 | + void updateReturnSalesLineWhenRqcFinish(Long sourceLineId, Long sourceDocId, Integer checkResult, | |
| 106 | + BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity); | |
| 94 | 107 | |
| 95 | 108 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.mes.service.wm.returnsales; |
| 2 | 2 | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 5 | 6 | import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWmReturnSalesLinePageReqVO; |
| ... | ... | @@ -7,14 +8,15 @@ import cn.iocoder.yudao.module.mes.controller.admin.wm.returnsales.vo.line.MesWm |
| 7 | 8 | import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO; |
| 8 | 9 | import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnsales.MesWmReturnSalesLineDO; |
| 9 | 10 | import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnsales.MesWmReturnSalesLineMapper; |
| 10 | -import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; | |
| 11 | 11 | import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum; |
| 12 | +import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnSalesStatusEnum; | |
| 12 | 13 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 13 | 14 | import jakarta.annotation.Resource; |
| 14 | 15 | import org.springframework.context.annotation.Lazy; |
| 15 | 16 | import org.springframework.stereotype.Service; |
| 16 | 17 | import org.springframework.validation.annotation.Validated; |
| 17 | 18 | |
| 19 | +import java.math.BigDecimal; | |
| 18 | 20 | import java.util.List; |
| 19 | 21 | import java.util.Objects; |
| 20 | 22 | |
| ... | ... | @@ -129,11 +131,48 @@ public class MesWmReturnSalesLineServiceImpl implements MesWmReturnSalesLineServ |
| 129 | 131 | } |
| 130 | 132 | |
| 131 | 133 | @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)); | |
| 134 | + public void updateReturnSalesLineWhenRqcFinish(Long sourceLineId, Long sourceDocId, Integer checkResult, | |
| 135 | + BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity) { | |
| 136 | + MesWmReturnSalesLineDO sourceLine = validateReturnSalesLineExists(sourceLineId); | |
| 137 | + boolean hasUnqualified = unqualifiedQuantity != null && unqualifiedQuantity.compareTo(BigDecimal.ZERO) > 0; | |
| 138 | + boolean hasQualified = qualifiedQuantity != null && qualifiedQuantity.compareTo(BigDecimal.ZERO) > 0; | |
| 139 | + | |
| 140 | + // 1. 根据合格/不合格品数量,更新退货单行的质量状态 | |
| 141 | + if (!hasUnqualified) { | |
| 142 | + // 1.A 情况一:全部合格 | |
| 143 | + returnSalesLineMapper.updateById(new MesWmReturnSalesLineDO() | |
| 144 | + .setId(sourceLineId).setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus())); | |
| 145 | + } else if (!hasQualified) { | |
| 146 | + // 1.B 情况二:全部不合格 | |
| 147 | + returnSalesLineMapper.updateById(new MesWmReturnSalesLineDO() | |
| 148 | + .setId(sourceLineId).setQualityStatus(MesWmQualityStatusEnum.FAIL.getStatus())); | |
| 149 | + } else { | |
| 150 | + // 1.C 情况三:部分合格部分不合格 → 拆分行 | |
| 151 | + // 1.C.1 新增一行不合格品 | |
| 152 | + MesWmReturnSalesLineDO unqualifiedLine = new MesWmReturnSalesLineDO() | |
| 153 | + .setReturnId(sourceLine.getReturnId()) | |
| 154 | + .setItemId(sourceLine.getItemId()) | |
| 155 | + .setQuantity(unqualifiedQuantity) | |
| 156 | + .setBatchId(sourceLine.getBatchId()) | |
| 157 | + .setQualityStatus(MesWmQualityStatusEnum.FAIL.getStatus()) | |
| 158 | + .setRemark(sourceLine.getRemark()); | |
| 159 | + returnSalesLineMapper.insert(unqualifiedLine); | |
| 160 | + // 1.C.2 更新原行为合格品 | |
| 161 | + returnSalesLineMapper.updateById(new MesWmReturnSalesLineDO() | |
| 162 | + .setId(sourceLineId) | |
| 163 | + .setQuantity(qualifiedQuantity) | |
| 164 | + .setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus())); | |
| 165 | + } | |
| 166 | + | |
| 167 | + // 2. 检查退货单下是否还有待检验的行,若全检完则将退货单状态设为"待上架" | |
| 168 | + if (sourceDocId != null) { | |
| 169 | + List<MesWmReturnSalesLineDO> allLines = returnSalesLineMapper.selectListByReturnId(sourceDocId); | |
| 170 | + boolean allInspected = !CollUtil.contains(allLines, | |
| 171 | + line -> Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.PENDING.getStatus())); | |
| 172 | + if (allInspected) { | |
| 173 | + returnSalesService.updateReturnSalesStatus(sourceDocId, MesWmReturnSalesStatusEnum.APPROVED.getStatus()); | |
| 174 | + } | |
| 175 | + } | |
| 137 | 176 | } |
| 138 | 177 | |
| 139 | 178 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesService.java
| ... | ... | @@ -88,6 +88,14 @@ public interface MesWmReturnSalesService { |
| 88 | 88 | void cancelReturnSales(Long id); |
| 89 | 89 | |
| 90 | 90 | /** |
| 91 | + * 更新销售退货单状态(供外部模块联动调用,如 RQC 检验完成后) | |
| 92 | + * | |
| 93 | + * @param id 编号 | |
| 94 | + * @param status 目标状态 | |
| 95 | + */ | |
| 96 | + void updateReturnSalesStatus(Long id, Integer status); | |
| 97 | + | |
| 98 | + /** | |
| 91 | 99 | * 校验销售退货单的数量:每行明细数量之和是否等于行退货数量 |
| 92 | 100 | * |
| 93 | 101 | * @param id 编号 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesServiceImpl.java
| ... | ... | @@ -239,4 +239,10 @@ public class MesWmReturnSalesServiceImpl implements MesWmReturnSalesService { |
| 239 | 239 | return returnSales; |
| 240 | 240 | } |
| 241 | 241 | |
| 242 | + @Override | |
| 243 | + public void updateReturnSalesStatus(Long id, Integer status) { | |
| 244 | + validateReturnSalesExists(id); | |
| 245 | + returnSalesMapper.updateById(new MesWmReturnSalesDO().setId(id).setStatus(status)); | |
| 246 | + } | |
| 247 | + | |
| 242 | 248 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/qc/rqc/MesQcRqcServiceImplTest.java
| ... | ... | @@ -16,15 +16,15 @@ import org.junit.jupiter.api.Test; |
| 16 | 16 | import org.springframework.context.annotation.Import; |
| 17 | 17 | import org.springframework.test.context.bean.override.mockito.MockitoBean; |
| 18 | 18 | |
| 19 | +import java.math.BigDecimal; | |
| 20 | + | |
| 19 | 21 | import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException; |
| 20 | 22 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; |
| 21 | 23 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; |
| 22 | 24 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_RQC_NOT_EXISTS; |
| 23 | 25 | import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.QC_RQC_NOT_PREPARE; |
| 24 | 26 | 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; | |
| 27 | +import static org.mockito.ArgumentMatchers.*; | |
| 28 | 28 | import static org.mockito.Mockito.never; |
| 29 | 29 | import static org.mockito.Mockito.verify; |
| 30 | 30 | |
| ... | ... | @@ -61,18 +61,22 @@ public class MesQcRqcServiceImplTest extends BaseDbUnitTest { |
| 61 | 61 | public void testFinishRqc_successWithReturnIssue() { |
| 62 | 62 | // 准备参数 |
| 63 | 63 | Long sourceLineId = randomLongId(); |
| 64 | + Long sourceDocId = randomLongId(); | |
| 64 | 65 | Integer checkResult = 1; |
| 66 | + BigDecimal qualifiedQty = new BigDecimal("80"); | |
| 67 | + BigDecimal unqualifiedQty = new BigDecimal("20"); | |
| 65 | 68 | |
| 66 | 69 | // mock 数据 |
| 67 | 70 | MesQcRqcDO rqc = randomPojo(MesQcRqcDO.class, o -> { |
| 68 | 71 | o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); |
| 69 | 72 | o.setSourceDocType(MesBizTypeConstants.WM_RETURN_ISSUE); |
| 73 | + o.setSourceDocId(sourceDocId); | |
| 70 | 74 | o.setSourceLineId(sourceLineId); |
| 71 | 75 | o.setCheckResult(checkResult); |
| 72 | 76 | // 设置数量通过 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")); | |
| 77 | + o.setCheckQuantity(new BigDecimal("100")); | |
| 78 | + o.setQualifiedQuantity(qualifiedQty); | |
| 79 | + o.setUnqualifiedQuantity(unqualifiedQty); | |
| 76 | 80 | }); |
| 77 | 81 | rqcMapper.insert(rqc); |
| 78 | 82 | |
| ... | ... | @@ -83,28 +87,36 @@ public class MesQcRqcServiceImplTest extends BaseDbUnitTest { |
| 83 | 87 | MesQcRqcDO updatedRqc = rqcMapper.selectById(rqc.getId()); |
| 84 | 88 | assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedRqc.getStatus()); |
| 85 | 89 | |
| 86 | - // 断言:验证回写调用生产退料 | |
| 87 | - verify(returnIssueLineService).updateReturnIssueLineWhenRqcFinish(eq(sourceLineId), eq(checkResult)); | |
| 90 | + // 断言:验证回写调用生产退料(含拆分参数) | |
| 91 | + verify(returnIssueLineService).updateReturnIssueLineWhenRqcFinish( | |
| 92 | + eq(sourceLineId), eq(sourceDocId), eq(checkResult), | |
| 93 | + argThat(v -> v.compareTo(qualifiedQty) == 0), | |
| 94 | + argThat(v -> v.compareTo(unqualifiedQty) == 0)); | |
| 88 | 95 | // 断言:未调用销售退货 |
| 89 | - verify(returnSalesLineService, never()).updateReturnSalesLineWhenRqcFinish(anyLong(), anyInt()); | |
| 96 | + verify(returnSalesLineService, never()).updateReturnSalesLineWhenRqcFinish( | |
| 97 | + anyLong(), anyLong(), anyInt(), any(BigDecimal.class), any(BigDecimal.class)); | |
| 90 | 98 | } |
| 91 | 99 | |
| 92 | 100 | @Test |
| 93 | 101 | public void testFinishRqc_successWithReturnSales() { |
| 94 | 102 | // 准备参数 |
| 95 | 103 | Long sourceLineId = randomLongId(); |
| 104 | + Long sourceDocId = randomLongId(); | |
| 96 | 105 | Integer checkResult = 1; |
| 106 | + BigDecimal qualifiedQty = new BigDecimal("90"); | |
| 107 | + BigDecimal unqualifiedQty = new BigDecimal("10"); | |
| 97 | 108 | |
| 98 | 109 | // mock 数据 |
| 99 | 110 | MesQcRqcDO rqc = randomPojo(MesQcRqcDO.class, o -> { |
| 100 | 111 | o.setStatus(MesQcStatusEnum.DRAFT.getStatus()); |
| 101 | 112 | o.setSourceDocType(MesBizTypeConstants.WM_RETURN_SALES); |
| 113 | + o.setSourceDocId(sourceDocId); | |
| 102 | 114 | o.setSourceLineId(sourceLineId); |
| 103 | 115 | o.setCheckResult(checkResult); |
| 104 | 116 | // 设置数量通过 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")); | |
| 117 | + o.setCheckQuantity(new BigDecimal("100")); | |
| 118 | + o.setQualifiedQuantity(qualifiedQty); | |
| 119 | + o.setUnqualifiedQuantity(unqualifiedQty); | |
| 108 | 120 | }); |
| 109 | 121 | rqcMapper.insert(rqc); |
| 110 | 122 | |
| ... | ... | @@ -115,10 +127,14 @@ public class MesQcRqcServiceImplTest extends BaseDbUnitTest { |
| 115 | 127 | MesQcRqcDO updatedRqc = rqcMapper.selectById(rqc.getId()); |
| 116 | 128 | assertEquals(MesQcStatusEnum.FINISHED.getStatus(), updatedRqc.getStatus()); |
| 117 | 129 | |
| 118 | - // 断言:验证回写调用销售退货 | |
| 119 | - verify(returnSalesLineService).updateReturnSalesLineWhenRqcFinish(eq(sourceLineId), eq(checkResult)); | |
| 130 | + // 断言:验证回写调用销售退货(含拆分参数) | |
| 131 | + verify(returnSalesLineService).updateReturnSalesLineWhenRqcFinish( | |
| 132 | + eq(sourceLineId), eq(sourceDocId), eq(checkResult), | |
| 133 | + argThat(v -> v.compareTo(qualifiedQty) == 0), | |
| 134 | + argThat(v -> v.compareTo(unqualifiedQty) == 0)); | |
| 120 | 135 | // 断言:未调用生产退料 |
| 121 | - verify(returnIssueLineService, never()).updateReturnIssueLineWhenRqcFinish(anyLong(), anyInt()); | |
| 136 | + verify(returnIssueLineService, never()).updateReturnIssueLineWhenRqcFinish( | |
| 137 | + anyLong(), anyLong(), anyInt(), any(BigDecimal.class), any(BigDecimal.class)); | |
| 122 | 138 | } |
| 123 | 139 | |
| 124 | 140 | @Test | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/returnissue/MesWmReturnIssueLineServiceImplTest.java
| ... | ... | @@ -12,8 +12,11 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; |
| 12 | 12 | |
| 13 | 13 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 14 | 14 | |
| 15 | +import java.math.BigDecimal; | |
| 16 | + | |
| 15 | 17 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; |
| 16 | 18 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| 19 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | |
| 17 | 20 | |
| 18 | 21 | /** |
| 19 | 22 | * {@link MesWmReturnIssueLineServiceImpl} 的单元测试类 |
| ... | ... | @@ -36,37 +39,75 @@ public class MesWmReturnIssueLineServiceImplTest extends BaseDbUnitTest { |
| 36 | 39 | private MesMdItemService itemService; |
| 37 | 40 | |
| 38 | 41 | @Test |
| 39 | - public void testUpdateReturnIssueLineWhenRqcFinish_pass() { | |
| 40 | - // 准备参数 | |
| 42 | + public void testUpdateReturnIssueLineWhenRqcFinish_allPass() { | |
| 43 | + // 准备参数:全部合格 | |
| 41 | 44 | Integer checkResult = MesQcCheckResultEnum.PASS.getType(); |
| 45 | + BigDecimal qualifiedQty = new BigDecimal("100"); | |
| 46 | + BigDecimal unqualifiedQty = BigDecimal.ZERO; | |
| 42 | 47 | |
| 43 | 48 | // mock 数据 |
| 44 | - MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class); | |
| 49 | + MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class, o -> o.setQuantity(qualifiedQty)); | |
| 45 | 50 | returnIssueLineMapper.insert(lineDO); |
| 46 | 51 | |
| 47 | - // 调用 | |
| 48 | - returnIssueLineService.updateReturnIssueLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 52 | + // 调用(sourceDocId 传 null 不联动主表状态) | |
| 53 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish( | |
| 54 | + lineDO.getId(), null, checkResult, qualifiedQty, unqualifiedQty); | |
| 49 | 55 | |
| 50 | - // 断言:验证 mapper 更新参数正确 | |
| 56 | + // 断言:验证质量状态更新为合格 | |
| 51 | 57 | MesWmReturnIssueLineDO updateLine = returnIssueLineMapper.selectById(lineDO.getId()); |
| 52 | 58 | assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), updateLine.getQualityStatus()); |
| 53 | 59 | } |
| 54 | 60 | |
| 55 | 61 | @Test |
| 56 | - public void testUpdateReturnIssueLineWhenRqcFinish_fail() { | |
| 57 | - // 准备参数 | |
| 62 | + public void testUpdateReturnIssueLineWhenRqcFinish_allFail() { | |
| 63 | + // 准备参数:全部不合格 | |
| 58 | 64 | Integer checkResult = MesQcCheckResultEnum.FAIL.getType(); |
| 65 | + BigDecimal qualifiedQty = BigDecimal.ZERO; | |
| 66 | + BigDecimal unqualifiedQty = new BigDecimal("100"); | |
| 59 | 67 | |
| 60 | 68 | // mock 数据 |
| 61 | - MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class); | |
| 69 | + MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class, o -> o.setQuantity(unqualifiedQty)); | |
| 62 | 70 | returnIssueLineMapper.insert(lineDO); |
| 63 | 71 | |
| 64 | 72 | // 调用 |
| 65 | - returnIssueLineService.updateReturnIssueLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 73 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish( | |
| 74 | + lineDO.getId(), null, checkResult, qualifiedQty, unqualifiedQty); | |
| 66 | 75 | |
| 67 | - // 断言:验证 mapper 更新参数正确 | |
| 76 | + // 断言:验证质量状态更新为不合格 | |
| 68 | 77 | MesWmReturnIssueLineDO updateLine = returnIssueLineMapper.selectById(lineDO.getId()); |
| 69 | 78 | assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), updateLine.getQualityStatus()); |
| 70 | 79 | } |
| 71 | 80 | |
| 81 | + @Test | |
| 82 | + public void testUpdateReturnIssueLineWhenRqcFinish_partialSplit() { | |
| 83 | + // 准备参数:部分合格部分不合格,触发行拆分 | |
| 84 | + Integer checkResult = MesQcCheckResultEnum.PASS.getType(); | |
| 85 | + BigDecimal qualifiedQty = new BigDecimal("80"); | |
| 86 | + BigDecimal unqualifiedQty = new BigDecimal("20"); | |
| 87 | + | |
| 88 | + // mock 数据 | |
| 89 | + MesWmReturnIssueLineDO lineDO = randomPojo(MesWmReturnIssueLineDO.class, o -> | |
| 90 | + o.setQuantity(new BigDecimal("100"))); | |
| 91 | + returnIssueLineMapper.insert(lineDO); | |
| 92 | + | |
| 93 | + // 调用 | |
| 94 | + returnIssueLineService.updateReturnIssueLineWhenRqcFinish( | |
| 95 | + lineDO.getId(), null, checkResult, qualifiedQty, unqualifiedQty); | |
| 96 | + | |
| 97 | + // 断言:原行变为合格,数量调整为合格数量 | |
| 98 | + MesWmReturnIssueLineDO originalLine = returnIssueLineMapper.selectById(lineDO.getId()); | |
| 99 | + assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), originalLine.getQualityStatus()); | |
| 100 | + assertEquals(0, qualifiedQty.compareTo(originalLine.getQuantity())); | |
| 101 | + | |
| 102 | + // 断言:新增了一行不合格品 | |
| 103 | + var allLines = returnIssueLineMapper.selectListByIssueId(lineDO.getIssueId()); | |
| 104 | + assertEquals(2, allLines.size()); | |
| 105 | + MesWmReturnIssueLineDO newLine = allLines.stream() | |
| 106 | + .filter(l -> !l.getId().equals(lineDO.getId())) | |
| 107 | + .findFirst().orElse(null); | |
| 108 | + assertNotNull(newLine); | |
| 109 | + assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), newLine.getQualityStatus()); | |
| 110 | + assertEquals(0, unqualifiedQty.compareTo(newLine.getQuantity())); | |
| 111 | + } | |
| 112 | + | |
| 72 | 113 | } | ... | ... |
yudao-module-mes/src/test/java/cn/iocoder/yudao/module/mes/service/wm/returnsales/MesWmReturnSalesLineServiceImplTest.java
| ... | ... | @@ -12,8 +12,11 @@ import org.springframework.test.context.bean.override.mockito.MockitoBean; |
| 12 | 12 | |
| 13 | 13 | import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService; |
| 14 | 14 | |
| 15 | +import java.math.BigDecimal; | |
| 16 | + | |
| 15 | 17 | import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; |
| 16 | 18 | import static org.junit.jupiter.api.Assertions.assertEquals; |
| 19 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | |
| 17 | 20 | |
| 18 | 21 | /** |
| 19 | 22 | * {@link MesWmReturnSalesLineServiceImpl} 的单元测试类 |
| ... | ... | @@ -36,37 +39,75 @@ public class MesWmReturnSalesLineServiceImplTest extends BaseDbUnitTest { |
| 36 | 39 | private MesMdItemService itemService; |
| 37 | 40 | |
| 38 | 41 | @Test |
| 39 | - public void testUpdateReturnSalesLineWhenRqcFinish_pass() { | |
| 40 | - // 准备参数 | |
| 42 | + public void testUpdateReturnSalesLineWhenRqcFinish_allPass() { | |
| 43 | + // 准备参数:全部合格 | |
| 41 | 44 | Integer checkResult = MesQcCheckResultEnum.PASS.getType(); |
| 45 | + BigDecimal qualifiedQty = new BigDecimal("100"); | |
| 46 | + BigDecimal unqualifiedQty = BigDecimal.ZERO; | |
| 42 | 47 | |
| 43 | 48 | // mock 数据 |
| 44 | - MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class); | |
| 49 | + MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class, o -> o.setQuantity(qualifiedQty)); | |
| 45 | 50 | returnSalesLineMapper.insert(lineDO); |
| 46 | 51 | |
| 47 | - // 调用 | |
| 48 | - returnSalesLineService.updateReturnSalesLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 52 | + // 调用(sourceDocId 传 null 不联动主表状态) | |
| 53 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish( | |
| 54 | + lineDO.getId(), null, checkResult, qualifiedQty, unqualifiedQty); | |
| 49 | 55 | |
| 50 | - // 断言:验证 mapper 更新参数正确 | |
| 56 | + // 断言:验证质量状态更新为合格 | |
| 51 | 57 | MesWmReturnSalesLineDO updateLine = returnSalesLineMapper.selectById(lineDO.getId()); |
| 52 | 58 | assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), updateLine.getQualityStatus()); |
| 53 | 59 | } |
| 54 | 60 | |
| 55 | 61 | @Test |
| 56 | - public void testUpdateReturnSalesLineWhenRqcFinish_fail() { | |
| 57 | - // 准备参数 | |
| 62 | + public void testUpdateReturnSalesLineWhenRqcFinish_allFail() { | |
| 63 | + // 准备参数:全部不合格 | |
| 58 | 64 | Integer checkResult = MesQcCheckResultEnum.FAIL.getType(); |
| 65 | + BigDecimal qualifiedQty = BigDecimal.ZERO; | |
| 66 | + BigDecimal unqualifiedQty = new BigDecimal("100"); | |
| 59 | 67 | |
| 60 | 68 | // mock 数据 |
| 61 | - MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class); | |
| 69 | + MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class, o -> o.setQuantity(unqualifiedQty)); | |
| 62 | 70 | returnSalesLineMapper.insert(lineDO); |
| 63 | 71 | |
| 64 | 72 | // 调用 |
| 65 | - returnSalesLineService.updateReturnSalesLineWhenRqcFinish(lineDO.getId(), checkResult); | |
| 73 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish( | |
| 74 | + lineDO.getId(), null, checkResult, qualifiedQty, unqualifiedQty); | |
| 66 | 75 | |
| 67 | - // 断言:验证 mapper 更新参数正确 | |
| 76 | + // 断言:验证质量状态更新为不合格 | |
| 68 | 77 | MesWmReturnSalesLineDO updateLine = returnSalesLineMapper.selectById(lineDO.getId()); |
| 69 | 78 | assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), updateLine.getQualityStatus()); |
| 70 | 79 | } |
| 71 | 80 | |
| 81 | + @Test | |
| 82 | + public void testUpdateReturnSalesLineWhenRqcFinish_partialSplit() { | |
| 83 | + // 准备参数:部分合格部分不合格,触发行拆分 | |
| 84 | + Integer checkResult = MesQcCheckResultEnum.PASS.getType(); | |
| 85 | + BigDecimal qualifiedQty = new BigDecimal("70"); | |
| 86 | + BigDecimal unqualifiedQty = new BigDecimal("30"); | |
| 87 | + | |
| 88 | + // mock 数据 | |
| 89 | + MesWmReturnSalesLineDO lineDO = randomPojo(MesWmReturnSalesLineDO.class, o -> | |
| 90 | + o.setQuantity(new BigDecimal("100"))); | |
| 91 | + returnSalesLineMapper.insert(lineDO); | |
| 92 | + | |
| 93 | + // 调用 | |
| 94 | + returnSalesLineService.updateReturnSalesLineWhenRqcFinish( | |
| 95 | + lineDO.getId(), null, checkResult, qualifiedQty, unqualifiedQty); | |
| 96 | + | |
| 97 | + // 断言:原行变为合格,数量调整为合格数量 | |
| 98 | + MesWmReturnSalesLineDO originalLine = returnSalesLineMapper.selectById(lineDO.getId()); | |
| 99 | + assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), originalLine.getQualityStatus()); | |
| 100 | + assertEquals(0, qualifiedQty.compareTo(originalLine.getQuantity())); | |
| 101 | + | |
| 102 | + // 断言:新增了一行不合格品 | |
| 103 | + var allLines = returnSalesLineMapper.selectListByReturnId(lineDO.getReturnId()); | |
| 104 | + assertEquals(2, allLines.size()); | |
| 105 | + MesWmReturnSalesLineDO newLine = allLines.stream() | |
| 106 | + .filter(l -> !l.getId().equals(lineDO.getId())) | |
| 107 | + .findFirst().orElse(null); | |
| 108 | + assertNotNull(newLine); | |
| 109 | + assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), newLine.getQualityStatus()); | |
| 110 | + assertEquals(0, unqualifiedQty.compareTo(newLine.getQuantity())); | |
| 111 | + } | |
| 112 | + | |
| 72 | 113 | } | ... | ... |