Commit dfeb3c104d48d1b8844c9850bf55c924f51e37ef
1 parent
b31f78c8
✨ feat(mes): 更新销售出库单状态流转逻辑,添加 OQC 检验支持
优化销售出库单的状态流转逻辑,新增待检测状态以支持 OQC 检验。根据检验结果自动流转状态,提升出库流程的灵活性和准确性。
Showing
6 changed files
with
64 additions
and
11 deletions
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
| ... | ... | @@ -533,7 +533,8 @@ public interface ErrorCodeConstants { |
| 533 | 533 | ErrorCode WM_PRODUCT_SALES_CANNOT_SHIPPING = new ErrorCode(1_040_714_006, "当前状态不允许填写运单"); |
| 534 | 534 | ErrorCode WM_PRODUCT_SALES_CANNOT_FINISH = new ErrorCode(1_040_714_007, "当前状态不允许执行出库"); |
| 535 | 535 | ErrorCode WM_PRODUCT_SALES_CANNOT_CANCEL = new ErrorCode(1_040_714_008, "当前状态不允许取消"); |
| 536 | - ErrorCode WM_PRODUCT_SALES_DETAILS_EMPTY = new ErrorCode(1_040_714_009, "拣货明细不能为空"); | |
| 536 | + ErrorCode WM_PRODUCT_SALES_CANNOT_CONFIRM = new ErrorCode(1_040_714_009, "当前状态不允许确认检验通过"); | |
| 537 | + ErrorCode WM_PRODUCT_SALES_DETAILS_EMPTY = new ErrorCode(1_040_714_020, "拣货明细不能为空"); | |
| 537 | 538 | ErrorCode WM_PRODUCT_SALES_DETAIL_QUANTITY_MISMATCH = new ErrorCode(1_040_714_010, "拣货数量与出库数量不匹配"); |
| 538 | 539 | ErrorCode WM_PRODUCT_SALES_LINE_NOT_EXISTS = new ErrorCode(1_040_714_011, "销售出库单行不存在"); |
| 539 | 540 | ErrorCode WM_PRODUCT_SALES_DETAIL_NOT_EXISTS = new ErrorCode(1_040_714_012, "销售出库明细不存在"); | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/wm/MesWmProductSalesStatusEnum.java
| ... | ... | @@ -28,10 +28,18 @@ public enum MesWmProductSalesStatusEnum implements ArrayValuable<Integer> { |
| 28 | 28 | */ |
| 29 | 29 | PREPARE(MesOrderStatusConstants.PREPARE, "草稿"), |
| 30 | 30 | /** |
| 31 | - * 待拣货 | |
| 31 | + * 待检测(需要 OQC 检验时),对接 qc 模块的 MesQcOqcDO 后续流程 | |
| 32 | 32 | * |
| 33 | 33 | * 对应方法:{@link MesWmProductSalesService#submitProductSales(Long)} |
| 34 | 34 | */ |
| 35 | + CONFIRMED(MesOrderStatusConstants.CONFIRMED, "待检测"), | |
| 36 | + /** | |
| 37 | + * 待拣货 | |
| 38 | + * | |
| 39 | + * 对应方法: | |
| 40 | + * 1. 不需要 OQC 检验时:{@link MesWmProductSalesService#submitProductSales(Long)} | |
| 41 | + * 2. 或 OQC 检验完成时:{@link MesWmProductSalesService#confirmProductSales(Long)} | |
| 42 | + */ | |
| 35 | 43 | APPROVING(MesOrderStatusConstants.APPROVING, "待拣货"), |
| 36 | 44 | /** |
| 37 | 45 | * 待填写运单 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesLineServiceImpl.java
| ... | ... | @@ -115,19 +115,30 @@ public class MesWmProductSalesLineServiceImpl implements MesWmProductSalesLineSe |
| 115 | 115 | productSalesLineMapper.updateById(new MesWmProductSalesLineDO() |
| 116 | 116 | .setId(id).setOqcId(oqcId).setQualityStatus(qualityStatus)); |
| 117 | 117 | |
| 118 | - // 2. 检查同一出库单下所有需要 OQC 检验的行的质检状态,联动更新出库单整体状态 | |
| 118 | + // 2. 检查同一出库单下所有需要 OQC 检验的行 | |
| 119 | 119 | MesWmProductSalesLineDO currentLine = productSalesLineMapper.selectById(id); |
| 120 | 120 | if (currentLine == null || currentLine.getSalesId() == null) { |
| 121 | 121 | return; |
| 122 | 122 | } |
| 123 | 123 | Long salesId = currentLine.getSalesId(); |
| 124 | 124 | List<MesWmProductSalesLineDO> allLines = productSalesLineMapper.selectListBySalesId(salesId); |
| 125 | + | |
| 126 | + // 2.1 检查是否有不合格行 → 取消出库单 | |
| 125 | 127 | boolean hasNg = CollectionUtils.anyMatch(allLines, |
| 126 | 128 | line -> Boolean.TRUE.equals(line.getOqcCheckFlag()) |
| 127 | 129 | && Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.FAIL.getStatus())); |
| 128 | 130 | if (hasNg) { |
| 129 | 131 | log.info("[updateProductSalesLineWhenOqcFinish][销售出库单({}) 存在质检不合格行,取消出库单]", salesId); |
| 130 | 132 | productSalesService.cancelProductSales(salesId); |
| 133 | + return; | |
| 134 | + } | |
| 135 | + | |
| 136 | + // 2.2 检查是否所有 OQC 行都已完成,自动流转 CONFIRMED → APPROVING | |
| 137 | + boolean hasUnchecked = CollectionUtils.anyMatch(allLines, | |
| 138 | + line -> Boolean.TRUE.equals(line.getOqcCheckFlag()) && line.getOqcId() == null); | |
| 139 | + if (!hasUnchecked) { | |
| 140 | + log.info("[updateProductSalesLineWhenOqcFinish][销售出库单({}) 所有 OQC 行检验完成,流转到待拣货]", salesId); | |
| 141 | + productSalesService.confirmProductSales(salesId); | |
| 131 | 142 | } |
| 132 | 143 | } |
| 133 | 144 | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesService.java
| ... | ... | @@ -53,7 +53,11 @@ public interface MesWmProductSalesService { |
| 53 | 53 | PageResult<MesWmProductSalesDO> getProductSalesPage(MesWmProductSalesPageReqVO pageReqVO); |
| 54 | 54 | |
| 55 | 55 | /** |
| 56 | - * 提交销售出库单(草稿 → 待拣货) | |
| 56 | + * 提交销售出库单 | |
| 57 | + * <ul> | |
| 58 | + * <li>有 OQC 检验行:草稿 → 待检测</li> | |
| 59 | + * <li>无 OQC 检验行:草稿 → 待拣货</li> | |
| 60 | + * </ul> | |
| 57 | 61 | * |
| 58 | 62 | * @param id 编号 |
| 59 | 63 | */ |
| ... | ... | @@ -95,4 +99,11 @@ public interface MesWmProductSalesService { |
| 95 | 99 | */ |
| 96 | 100 | void cancelProductSales(Long id); |
| 97 | 101 | |
| 102 | + /** | |
| 103 | + * OQC 检验完成后,自动流转(待检测 → 待拣货) | |
| 104 | + * | |
| 105 | + * @param id 编号 | |
| 106 | + */ | |
| 107 | + void confirmProductSales(Long id); | |
| 108 | + | |
| 98 | 109 | } | ... | ... |
yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/productsales/MesWmProductSalesServiceImpl.java
| ... | ... | @@ -117,7 +117,16 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService { |
| 117 | 117 | throw exception(WM_PRODUCT_SALES_LINES_EMPTY); |
| 118 | 118 | } |
| 119 | 119 | |
| 120 | - // 提交(草稿 → 待拣货) | |
| 120 | + // 检查所有行的 oqcCheckFlag:如果有需要 OQC 检验的行,进入待检测状态 | |
| 121 | + boolean needOqc = CollectionUtils.anyMatch(lines, | |
| 122 | + line -> Boolean.TRUE.equals(line.getOqcCheckFlag())); | |
| 123 | + if (needOqc) { | |
| 124 | + // 需要检验,进入待检测 | |
| 125 | + productSalesMapper.updateById(new MesWmProductSalesDO() | |
| 126 | + .setId(id).setStatus(MesWmProductSalesStatusEnum.CONFIRMED.getStatus())); | |
| 127 | + return; | |
| 128 | + } | |
| 129 | + // 不需要检验,直接进入待拣货 | |
| 121 | 130 | productSalesMapper.updateById(new MesWmProductSalesDO() |
| 122 | 131 | .setId(id).setStatus(MesWmProductSalesStatusEnum.APPROVING.getStatus())); |
| 123 | 132 | } |
| ... | ... | @@ -215,6 +224,18 @@ public class MesWmProductSalesServiceImpl implements MesWmProductSalesService { |
| 215 | 224 | .setId(id).setStatus(MesWmProductSalesStatusEnum.CANCELED.getStatus())); |
| 216 | 225 | } |
| 217 | 226 | |
| 227 | + @Override | |
| 228 | + public void confirmProductSales(Long id) { | |
| 229 | + // 校验存在 + 待检测状态 | |
| 230 | + MesWmProductSalesDO sales = validateProductSalesExists(id); | |
| 231 | + if (ObjUtil.notEqual(MesWmProductSalesStatusEnum.CONFIRMED.getStatus(), sales.getStatus())) { | |
| 232 | + throw exception(WM_PRODUCT_SALES_CANNOT_CONFIRM); | |
| 233 | + } | |
| 234 | + // OQC 检验完成,流转到待拣货 | |
| 235 | + productSalesMapper.updateById(new MesWmProductSalesDO() | |
| 236 | + .setId(id).setStatus(MesWmProductSalesStatusEnum.APPROVING.getStatus())); | |
| 237 | + } | |
| 238 | + | |
| 218 | 239 | private MesWmProductSalesDO validateProductSalesExists(Long id) { |
| 219 | 240 | MesWmProductSalesDO sales = productSalesMapper.selectById(id); |
| 220 | 241 | if (sales == null) { | ... | ... |
yudao-module-mes/src/main/resources/mapper/qc/pendinginspect/MesQcPendingInspectMapper.xml
| ... | ... | @@ -4,12 +4,12 @@ |
| 4 | 4 | |
| 5 | 5 | <!-- |
| 6 | 6 | 待检任务查询(UNION ALL 多来源),已实现的来源: |
| 7 | - 1. 到货通知单(IQC):单据状态=待质检(2),行的 iqc_check_flag=1 且 iqc_id 为空 | |
| 8 | - 2. 外协入库单(IQC):单据状态=待检验(1),行的 iqc_check_flag=1 且 iqc_id 为空 | |
| 9 | - 3. 生产报工(IPQC):单据状态=待检验(3) | |
| 10 | - 4. 销售出库单(OQC):无单据状态要求,行的 oqc_check_flag=1 且 oqc_id 为空 | |
| 11 | - 5. 生产退料单(RQC):单据状态=待检验(1),行的 rqc_check_flag=1 且 rqc_id 为空 且 quality_status=0(待检) | |
| 12 | - 6. 销售退货单(RQC):单据状态=待检验(1),行的 rqc_check_flag=1 且 rqc_id 为空 且 quality_status=0(待检) | |
| 7 | + 1. 到货通知单(IQC):单据状态=PENDING_QC(2),行的 iqc_check_flag=1 且 iqc_id 为空 | |
| 8 | + 2. 外协入库单(IQC):单据状态=CONFIRMED(1),行的 iqc_check_flag=1 且 iqc_id 为空 | |
| 9 | + 3. 生产报工(IPQC):单据状态=UNCHECK(3) | |
| 10 | + 4. 销售出库单(OQC):单据状态=CONFIRMED(1),行的 oqc_check_flag=1 且 oqc_id 为空 | |
| 11 | + 5. 生产退料单(RQC):单据状态=CONFIRMED(1),行的 rqc_check_flag=1 且 rqc_id 为空 且 quality_status=0(待检) | |
| 12 | + 6. 销售退货单(RQC):单据状态=CONFIRMED(1),行的 rqc_check_flag=1 且 rqc_id 为空 且 quality_status=0(待检) | |
| 13 | 13 | --> |
| 14 | 14 | <select id="selectQcPendingPage" resultType="cn.iocoder.yudao.module.mes.controller.admin.qc.pendinginspect.vo.MesQcPendingInspectRespVO"> |
| 15 | 15 | SELECT * FROM ( |
| ... | ... | @@ -103,6 +103,7 @@ |
| 103 | 103 | JOIN mes_wm_product_sales_line sl ON s.id = sl.sales_id |
| 104 | 104 | WHERE sl.oqc_check_flag = 1 |
| 105 | 105 | AND sl.oqc_id IS NULL |
| 106 | + AND s.status = ${@cn.iocoder.yudao.module.mes.enums.wm.MesWmProductSalesStatusEnum@CONFIRMED.status} | |
| 106 | 107 | AND s.deleted = 0 |
| 107 | 108 | AND sl.deleted = 0 |
| 108 | 109 | ... | ... |