yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/sale/ErpSaleOrderServiceImpl.java
@@ -18,6 +18,8 @@
import cn.iocoder.yudao.module.crm.api.customer.CrmCustomerApi;
import cn.iocoder.yudao.module.crm.api.customer.dto.CrmCustomerRespDTO;
import cn.iocoder.yudao.module.crm.api.contract.CrmContractApi;
import cn.iocoder.yudao.module.crm.api.contract.dto.CrmContractCreateFromSaleOrderReqDTO;
import cn.iocoder.yudao.module.crm.api.contract.dto.CrmContractRespDTO;
import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderPageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.sale.vo.order.ErpSaleOrderImportExcelVO;
@@ -440,9 +442,10 @@
                    .setId(id).setStatus(newStatus));
        }
        // 3. 审核通过时,为需要生产的明细创建 MPS
        // 3. 审核通过时,为需要生产的明细创建 MPS,并自动生成销售合同草稿
        if (ErpAuditStatus.APPROVE.getStatus().equals(newStatus)) {
            createMpsForSaleOrder(id, saleOrder);
            createContractForSaleOrder(saleOrder);
        }
    }
@@ -550,6 +553,58 @@
    }
    /**
     * 销售订单审批通过后,自动生成销售合同草稿(不提交审批)
     */
    private void createContractForSaleOrder(ErpSaleOrderDO saleOrder) {
        // 订单本身由合同生成,避免反向生成
        if (saleOrder.getContractId() != null) {
            log.info("[createContractForSaleOrder] 销售订单({}) 已关联合同({}),跳过自动生成",
                    saleOrder.getNo(), saleOrder.getContractNo());
            return;
        }
        try {
            List<ErpSaleOrderItemDO> items = saleOrderItemMapper.selectListByOrderId(saleOrder.getId());
            if (CollUtil.isEmpty(items)) {
                log.warn("[createContractForSaleOrder] 销售订单({}) 没有明细,跳过自动生成合同", saleOrder.getNo());
                return;
            }
            // 负责人优先取销售员,未填写时回退到订单创建人
            Long ownerUserId = saleOrder.getSaleUserId();
            if (ownerUserId == null && StrUtil.isNumeric(saleOrder.getCreator())) {
                ownerUserId = Long.valueOf(saleOrder.getCreator());
            }
            CrmContractCreateFromSaleOrderReqDTO createReqDTO = new CrmContractCreateFromSaleOrderReqDTO();
            createReqDTO.setOrderId(saleOrder.getId());
            createReqDTO.setOrderNo(saleOrder.getNo());
            createReqDTO.setCustomerId(saleOrder.getCustomerId());
            createReqDTO.setOwnerUserId(ownerUserId);
            createReqDTO.setOrderTime(saleOrder.getOrderTime());
            createReqDTO.setDiscountPercent(saleOrder.getDiscountPercent());
            createReqDTO.setDepositPrice(saleOrder.getDepositPrice());
            createReqDTO.setItems(items.stream().map(item -> {
                CrmContractCreateFromSaleOrderReqDTO.Item contractItem = new CrmContractCreateFromSaleOrderReqDTO.Item();
                contractItem.setItemId(item.getProductId());
                contractItem.setItemUnitId(item.getProductUnitId());
                contractItem.setPrice(item.getProductPrice());
                contractItem.setCount(item.getCount());
                return contractItem;
            }).toList());
            CrmContractRespDTO contract = contractApi.createContractDraftFromSaleOrder(createReqDTO).getCheckedData();
            if (contract != null) {
                saleOrderMapper.updateById(new ErpSaleOrderDO().setId(saleOrder.getId())
                        .setContractId(contract.getId()).setContractNo(contract.getNo()));
                log.info("[createContractForSaleOrder] 销售订单({}) 自动生成合同({}) 成功",
                        saleOrder.getNo(), contract.getNo());
            }
        } catch (Exception e) {
            // 合同生成失败不阻塞订单审批,记录日志便于排查
            log.error("[createContractForSaleOrder] 销售订单({}) 自动生成销售合同失败", saleOrder.getNo(), e);
        }
    }
    /**
     * 为销售订单明细创建 MPS
     */
    private Long createMpsForSaleOrderItem(ErpSaleOrderDO saleOrder, ErpSaleOrderItemDO item) {