云
5 天以前 1d9cfc91e7255b9e139b20ff230cb19246f19193
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/purchase/ErpPurchaseRequestServiceImpl.java
@@ -114,10 +114,8 @@
            supplierService.validateSupplier(createReqVO.getSupplierId());
        }
        // 3. 生成申请单号
        String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_REQUEST_NO_PREFIX);
        if (purchaseRequestMapper.selectByNo(no) != null) {
            throw exception(PURCHASE_REQUEST_NO_EXISTS);
        }
        String no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_REQUEST_NO_PREFIX,
                candidate -> purchaseRequestMapper.selectByNo(candidate) != null);
        // 4. 获取当前用户信息
        Long userId = Long.parseLong(getCurrentUserId());
@@ -276,10 +274,15 @@
        }
        // 3. 单号:填了就用(校验唯一),没填自动生成 CGSQ...
        String no = StrUtil.isNotBlank(head.getNo()) ? head.getNo().trim()
                : noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_REQUEST_NO_PREFIX);
        if (purchaseRequestMapper.selectByNo(no) != null) {
            throw new IllegalArgumentException("采购申请单号已存在:" + no);
        String no;
        if (StrUtil.isNotBlank(head.getNo())) {
            no = head.getNo().trim();
            if (purchaseRequestMapper.selectByNo(no) != null) {
                throw new IllegalArgumentException("采购申请单号已存在:" + no);
            }
        } else {
            no = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_REQUEST_NO_PREFIX,
                    candidate -> purchaseRequestMapper.selectByNo(candidate) != null);
        }
        // 4. 申请人 / 申请部门:取当前登录用户及其部门
@@ -360,7 +363,8 @@
        purchaseRequest.setTotalCount(getSumValue(requestItems, ErpPurchaseRequestItemDO::getCount, BigDecimal::add));
        purchaseRequest.setTotalProductPrice(getSumValue(requestItems, ErpPurchaseRequestItemDO::getTotalPrice, BigDecimal::add, BigDecimal.ZERO));
        purchaseRequest.setTotalTaxPrice(getSumValue(requestItems, ErpPurchaseRequestItemDO::getTaxPrice, BigDecimal::add, BigDecimal.ZERO));
        purchaseRequest.setTotalPrice(purchaseRequest.getTotalProductPrice().add(purchaseRequest.getTotalTaxPrice()));
        // 单价为含税单价:价税合计 = 单价 * 数量,税额已包含在单价中,不再额外加税
        purchaseRequest.setTotalPrice(purchaseRequest.getTotalProductPrice());
        // 计算优惠价格
        if (purchaseRequest.getDiscountPercent() == null) {
            purchaseRequest.setDiscountPercent(BigDecimal.ZERO);
@@ -374,7 +378,8 @@
            if (item.getProductPrice() != null && item.getCount() != null) {
                item.setTotalPrice(MoneyUtils.priceMultiply(item.getProductPrice(), item.getCount()));
                if (item.getTaxPercent() != null) {
                    item.setTaxPrice(MoneyUtils.priceMultiplyPercent(item.getTotalPrice(), item.getTaxPercent()));
                    // 单价为含税单价:税额从价税合计中反算,而不是在合计上再加税
                    item.setTaxPrice(MoneyUtils.taxPriceIncluded(item.getTotalPrice(), item.getTaxPercent()));
                }
            }
        }));
@@ -463,6 +468,16 @@
        }
        // 3. 创建 BPM 流程实例
        // 全局免审批:业务校验通过后直接执行审批通过逻辑,无需流程模型。
        if (processInstanceApi.isGlobalAutoApprove()) {
            purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
                    .setId(id)
                    .setStatus(ErpPurchaseRequestStatusEnum.PROCESS.getStatus())
                    .setProcessInstanceId(""));
            updatePurchaseRequestAuditStatus(id, cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.APPROVE.getStatus());
            return;
        }
        String processInstanceId = processInstanceApi.createProcessInstance(userId,
                new BpmProcessInstanceCreateReqDTO()
                        .setProcessDefinitionKey(processDefinitionKey)
@@ -555,11 +570,16 @@
        if (purchaseRequest.getOrderId() != null) {
            throw exception(PURCHASE_REQUEST_ORDER_EXISTS);
        }
        // 3. 校验供应商
        supplierService.validateSupplier(supplierId);
        // 3. 供应商以采购申请单为准:申请提交时已经选过供应商,生成订单不再要求重新选择
        //    兼容旧调用方仍显式传 supplierId 的情况,传了则以传入值为准
        Long targetSupplierId = supplierId != null ? supplierId : purchaseRequest.getSupplierId();
        if (targetSupplierId == null) {
            throw exception(PURCHASE_REQUEST_SUPPLIER_REQUIRED);
        }
        supplierService.validateSupplier(targetSupplierId);
        // 4. 设置供应商并生成订单
        purchaseRequest.setSupplierId(supplierId);
        purchaseRequest.setSupplierId(targetSupplierId);
        return doGeneratePurchaseOrder(purchaseRequest);
    }
@@ -579,15 +599,15 @@
        }
        // 2. 生成采购订单号
        String orderNo = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_ORDER_NO_PREFIX);
        if (purchaseOrderMapper.selectByNo(orderNo) != null) {
            throw exception(PURCHASE_ORDER_NO_EXISTS);
        }
        String orderNo = noRedisDAO.generate(ErpNoRedisDAO.PURCHASE_ORDER_NO_PREFIX,
                candidate -> purchaseOrderMapper.selectByNo(candidate) != null);
        // 3. 创建采购订单
        ErpPurchaseOrderDO purchaseOrder = new ErpPurchaseOrderDO();
        purchaseOrder.setNo(orderNo);
        purchaseOrder.setStatus(ErpAuditStatus.APPROVE.getStatus()); // 采购订单直接为已审核状态
        // 生成后为草稿:采购申请与采购台账字段不完全一致(付款日期、采购类型、付款方式等),
        // 需要业务在采购台账里补充完整后再提交审批
        purchaseOrder.setStatus(ErpAuditStatus.DRAFT.getStatus());
        purchaseOrder.setSupplierId(purchaseRequest.getSupplierId());
        purchaseOrder.setOrderTime(purchaseRequest.getRequestTime());
        purchaseOrder.setTotalCount(purchaseRequest.getTotalCount());
@@ -616,7 +636,8 @@
            orderItem.setTaxPrice(item.getTaxPrice());
            orderItem.setRemark(item.getRemark());
            orderItem.setInCount(BigDecimal.ZERO);
            orderItem.setQcCheckFlag(item.getQcCheckFlag() != null ? item.getQcCheckFlag() : false);
            // 是否质检与采购申请保持一致:明细未明确标记时默认为「是」(历史申请单可能为 null)
            orderItem.setQcCheckFlag(item.getQcCheckFlag() != null ? item.getQcCheckFlag() : true);
            return orderItem;
        });
        purchaseOrderItemMapper.insertBatch(orderItems);
@@ -624,6 +645,7 @@
        // 5. 更新采购申请的订单信息
        purchaseRequestMapper.updateById(new ErpPurchaseRequestDO()
                .setId(id)
                .setSupplierId(purchaseRequest.getSupplierId())
                .setOrderId(purchaseOrder.getId())
                .setOrderNo(orderNo));