From 4bc513be11e671caf20ec6013a51dee42c2ed96e Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期六, 07 十一月 2026 18:31:26 +0800
Subject: [PATCH] fix(crm): 禁止物料类合同开票

---
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java |   31 +++++++++++++++++++++++++++++++
 1 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
index 91e98c9..09fb01a 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/invoice/CrmInvoiceServiceImpl.java
@@ -13,6 +13,7 @@
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoicePageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.invoice.vo.invoice.CrmInvoiceSaveReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
+import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractProductDO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.invoice.CrmInvoiceDO;
 import cn.iocoder.yudao.module.crm.dal.mysql.invoice.CrmInvoiceMapper;
 import cn.iocoder.yudao.module.crm.dal.redis.no.CrmNoRedisDAO;
@@ -30,6 +31,9 @@
 import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
 import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
 import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
+import cn.iocoder.yudao.module.mdm.api.item.MdmItemApi;
+import cn.iocoder.yudao.module.mdm.api.item.dto.MdmItemRespDTO;
+import cn.iocoder.yudao.module.mdm.enums.MdmItemTypeEnum;
 import com.mzt.logapi.context.LogRecordContext;
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
@@ -87,6 +91,8 @@
     private CrmContractService contractService;
     @Resource
     private CrmPermissionService permissionService;
+    @Resource
+    private MdmItemApi mdmItemApi;
 
     @Resource
     private AdminUserApi adminUserApi;
@@ -104,6 +110,7 @@
     public Long createInvoice(CrmInvoiceSaveReqVO createReqVO) {
         // 1.1 鏍¢獙鍏宠仈鏁版嵁瀛樺湪锛堝紑绁ㄩ噾棰濅笉鍐嶅彈鍚堝悓閲戦闄愬埗锛屼粎鍓嶇鎻愮ず鍙紑绁ㄩ噾棰濓級
         validateRelationDataExists(createReqVO);
+        validateContractItemsInvoiceable(createReqVO.getContractId());
         // 1.3 鐢熸垚寮�绁ㄧ紪鍙�
         String no = noRedisDAO.generate(CrmNoRedisDAO.INVOICE_PREFIX);
         if (invoiceMapper.selectByNo(no) != null) {
@@ -140,6 +147,29 @@
                 throw exception(INVOICE_CREATE_FAIL_CONTRACT_NOT_APPROVE);
             }
             reqVO.setCustomerId(contract.getCustomerId()); // 璁剧疆瀹㈡埛缂栧彿
+        }
+    }
+
+    /**
+     * 鍚堝悓涓寘鍚墿鏂欐椂涓嶅厑璁稿紑绁紝鍙湁浜у搧绫婚攢鍞唴瀹规墠鍙繘鍏ュ紑绁ㄦ祦绋嬨��
+     */
+    void validateContractItemsInvoiceable(Long contractId) {
+        if (contractId == null) {
+            return;
+        }
+        List<CrmContractProductDO> contractProducts = contractService.getContractProductListByContractId(contractId);
+        if (CollUtil.isEmpty(contractProducts)) {
+            return;
+        }
+        Map<Long, MdmItemRespDTO> itemMap = mdmItemApi.getItemMap(
+                CollectionUtils.convertSet(contractProducts, CrmContractProductDO::getItemId));
+        boolean containsMaterial = contractProducts.stream()
+                .map(CrmContractProductDO::getItemId)
+                .map(itemMap::get)
+                .filter(ObjectUtil::isNotNull)
+                .anyMatch(item -> MdmItemTypeEnum.MATERIAL.getType().equals(item.getItemType()));
+        if (containsMaterial) {
+            throw exception(INVOICE_CREATE_FAIL_MATERIAL_NOT_ALLOWED);
         }
     }
 
@@ -210,6 +240,7 @@
                 && ObjUtil.notEqual(invoice.getAuditStatus(), CrmAuditStatusEnum.REJECT.getStatus())) {
             throw exception(INVOICE_SUBMIT_FAIL_NOT_EDITABLE);
         }
+        validateContractItemsInvoiceable(invoice.getContractId());
 
         // 2. 鏍¢獙瀹℃壒閰嶇疆宸插惎鐢ㄤ笖閰嶇疆浜嗘湁鏁堝鎵逛汉锛堟湭閰嶇疆鏃舵姏鍑哄甫鏄庣‘鎻愮ず鐨勪笟鍔″紓甯革級
         approvalConfigApi.validateApprovalEnabledAndGetApprovers(INVOICE_APPROVE_BIZ_TYPE);

--
Gitblit v1.9.3