yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/enums/ErrorCodeConstants.java
@@ -593,6 +593,7 @@ ErrorCode WM_ARRIVAL_NOTICE_NO_IQC_LINE = new ErrorCode(1_040_704_009, "到货通知单没有需要检验的明细行,无需生成来料检验单"); ErrorCode WM_ARRIVAL_NOTICE_IQC_ALREADY_CREATED = new ErrorCode(1_040_704_010, "到货通知单的需检行已全部生成来料检验单"); ErrorCode WM_ARRIVAL_NOTICE_IQC_CREATE_FAILED = new ErrorCode(1_040_704_011, "生成来料检验单失败"); ErrorCode WM_ARRIVAL_NOTICE_NO_QUALIFIED_LINE = new ErrorCode(1_040_704_012, "到货通知单没有可入库的合格数量"); ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_EXISTS = new ErrorCode(1_040_704_100, "到货通知单行不存在"); ErrorCode WM_ARRIVAL_NOTICE_LINE_NOT_MATCH = new ErrorCode(1_040_704_101, "到货通知单行不属于指定的到货通知单"); yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/arrivalnotice/MesWmArrivalNoticeServiceImpl.java
@@ -22,7 +22,6 @@ import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderItemRespDTO; import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService; import cn.iocoder.yudao.module.mes.service.qc.iqc.MesQcIqcService; import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum; import cn.iocoder.yudao.module.mes.service.wm.itemreceipt.MesWmItemReceiptService; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; @@ -260,16 +259,18 @@ return; } // 3.2 判断是否所有需检行都可以入库(合格或特采) boolean hasNonInbound = CollectionUtils.anyMatch(lines, line -> Boolean.TRUE.equals(line.getIqcCheckFlag()) && !MesQcCheckResultEnum.canInbound(line.getIqcCheckResult())); if (hasNonInbound) { log.info("[updateArrivalNoticeWhenIqcFinish][到货通知单({}) 存在不可入库的行(退货/报废),状态保持待质检]", id); // 3.2 判断是否存在可入库的合格数量:需检行取质检合格数量,无需检行取到货数量。 // 部分不合格时,合格部分照常入库;不合格部分由 NCR 单独处置(退货/让步接收),不再阻塞合格品入库。 boolean hasReceivable = CollectionUtils.anyMatch(lines, line -> { BigDecimal receivable = resolveReceivableQuantity(line); return receivable != null && receivable.signum() > 0; }); if (!hasReceivable) { log.info("[updateArrivalNoticeWhenIqcFinish][到货通知单({}) 各行的合格数量均为 0,状态保持待质检,等待不合格品处置]", id); return; } // 3.3 所有行检验完成且可入库,更新主表状态 PENDING_QC → PENDING_RECEIPT // 3.3 检验完成且存在可入库数量,更新主表状态 PENDING_QC → PENDING_RECEIPT arrivalNoticeMapper.updateById(new MesWmArrivalNoticeDO() .setId(id).setStatus(MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT.getStatus())); // 3.4 质检合格后直接生成采购入库单(待入库),库管只需核对数量并确认入库 @@ -277,6 +278,16 @@ } /** * 计算到货通知行本次可入库数量:需检行取质检合格数量,无需检行取到货数量。 */ private BigDecimal resolveReceivableQuantity(MesWmArrivalNoticeLineDO line) { if (Boolean.TRUE.equals(line.getIqcCheckFlag())) { return line.getQualifiedQuantity(); } return line.getArrivalQuantity(); } /** * 到货通知单进入「待入库」后自动生成采购入库单。 * 库管无需再回到到货通知点「执行入库」,直接到【采购入库】核对数量并确认入库即可。 */ yudao-module-mes/src/main/java/cn/iocoder/yudao/module/mes/service/wm/itemreceipt/MesWmItemReceiptServiceImpl.java
@@ -652,11 +652,12 @@ receipt.setStatus(MesWmItemReceiptStatusEnum.PREPARE.getStatus()); itemReceiptMapper.insert(receipt); // 6. 遍历行创建入库单行 // 6. 遍历行创建入库单行:需检行只入质检合格数量,无需检行入到货数量 int createdLineCount = 0; for (MesWmArrivalNoticeLineDO noticeLine : lines) { BigDecimal receivable = noticeLine.getQualifiedQuantity() != null BigDecimal receivable = Boolean.TRUE.equals(noticeLine.getIqcCheckFlag()) ? noticeLine.getQualifiedQuantity() : noticeLine.getArrivalQuantity(); // 整行已退供应商时不生成零数量入库行;其余行仍正常收货。 // 整行不合格(合格数量为 0)或无需检行未填写到货数量时,不生成零数量入库行 if (receivable == null || receivable.signum() <= 0) { continue; } @@ -665,11 +666,16 @@ receiptLine.setArrivalNoticeLineId(noticeLine.getId()); receiptLine.setPurchaseOrderItemId(noticeLine.getPurchaseOrderItemId()); receiptLine.setItemId(noticeLine.getItemId()); // 使用合格数量(如果有 IQC 则是合格数量,否则是到货数量) receiptLine.setReceivedQuantity(receivable); // 按采购订单行单价快照金额,供来票/对账使用 fillReceiptLinePrice(receiptLine); itemReceiptLineService.createItemReceiptLineFromArrivalNoticeLine(receiptLine); createdLineCount++; } if (createdLineCount == 0) { throw new ServiceException(WM_ARRIVAL_NOTICE_NO_QUALIFIED_LINE.getCode(), "到货通知单[" + notice.getCode() + "]没有可入库的合格数量:所有需检行的质检合格数量均为 0 或为空。" + "请先完成不合格品的处置(退货或让步接收),处置完成后再生成入库单。"); } return receipt.getId();