From a647bc8a43c0212f482bee0630ebd14dca120a8a Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期一, 28 九月 2026 14:13:28 +0800
Subject: [PATCH] feat: CRM 发票/合同导入、MES 质检批量导入与检测台账、回款与报价校验、权限码细化

---
 yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java |   74 ++++++++++++-------------------------
 1 files changed, 24 insertions(+), 50 deletions(-)

diff --git a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
index f655977..91b18a7 100644
--- a/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
+++ b/yudao-module-crm/src/main/java/cn/iocoder/yudao/module/crm/service/receivable/CrmReceivableServiceImpl.java
@@ -8,9 +8,6 @@
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
-import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
-import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivablePageReqVO;
 import cn.iocoder.yudao.module.crm.controller.admin.receivable.vo.receivable.CrmReceivableSaveReqVO;
 import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
@@ -34,7 +31,6 @@
 import com.mzt.logapi.service.impl.DiffParseFunction;
 import com.mzt.logapi.starter.annotation.LogRecord;
 import jakarta.annotation.Resource;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -46,7 +42,6 @@
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.module.crm.enums.LogRecordConstants.*;
-import static cn.iocoder.yudao.module.crm.util.CrmAuditStatusUtils.convertBpmResultToAuditStatus;
 
 /**
  * CRM 鍥炴 Service 瀹炵幇绫�
@@ -55,13 +50,7 @@
  */
 @Service
 @Validated
-@Slf4j
 public class CrmReceivableServiceImpl implements CrmReceivableService {
-
-    /**
-     * BPM 鍚堝悓瀹℃壒娴佺▼鏍囪瘑
-     */
-    public static final String BPM_PROCESS_DEFINITION_KEY = "crm-receivable-audit";
 
     @Resource
     private CrmReceivableMapper receivableMapper;
@@ -81,8 +70,6 @@
 
     @Resource
     private AdminUserApi adminUserApi;
-    @Resource
-    private BpmProcessInstanceApi bpmProcessInstanceApi;
     @Resource
     private StorageAttachmentApi storageAttachmentApi;
 
@@ -105,9 +92,9 @@
             throw exception(RECEIVABLE_NO_EXISTS);
         }
 
-        // 2.1 鎻掑叆鍥炴
+        // 2.1 鎻掑叆鍥炴锛堝垱寤哄悗鍗充负鏈鏍哥姸鎬侊級
         CrmReceivableDO receivable = BeanUtils.toBean(createReqVO, CrmReceivableDO.class)
-                .setNo(no).setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus());
+                .setNo(no).setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus());
         receivableMapper.insert(receivable);
         // 2.2
 
@@ -149,6 +136,10 @@
      * 鏍¢獙鍏宠仈寮�绁ㄥ悎鏍硷細瀛樺湪銆佸鎵归�氳繃銆佸凡涓婁紶鍙戠エ闄勪欢銆佷笌鎵�閫夊悎鍚屼竴鑷�
      */
     private void validateInvoiceForReceivable(CrmReceivableSaveReqVO reqVO) {
+        // 鏈叧鑱斿紑绁ㄦ椂鐩存帴璺宠繃锛堝厑璁稿厛鍥炴鍚庡紑绁級
+        if (reqVO.getInvoiceId() == null) {
+            return;
+        }
         // 1. 鏍¢獙寮�绁ㄥ瓨鍦�
         CrmInvoiceDO invoice = invoiceService.getInvoice(reqVO.getInvoiceId());
         if (invoice == null) {
@@ -177,6 +168,10 @@
      * 鏍¢獙绱鍥炴閲戦涓嶈秴杩囪寮�绁ㄥ墿浣欏彲鍥炴閲戦锛堝厛寮�绁ㄥ悗鍥炴锛�
      */
     private void validateReceivablePriceExceedsInvoiceRemaining(CrmReceivableSaveReqVO reqVO) {
+        // 鏈叧鑱斿紑绁ㄦ椂鐩存帴璺宠繃锛堥噾棰濅笂闄愪粛鐢卞悎鍚岀骇鏍¢獙 validateReceivablePriceExceedsLimit 鍏滃簳锛�
+        if (reqVO.getInvoiceId() == null) {
+            return;
+        }
         // 1. 璁$畻璇ュ紑绁ㄧ疮璁″洖娆鹃噾棰濓紙涓嶅惈鏈锛岀粺璁″彛寰勫悓鍚堝悓閲戦鏍¢獙锛氳崏绋� + 瀹℃壒涓� + 瀹℃壒閫氳繃锛�
         CrmInvoiceDO invoice = invoiceService.getInvoice(reqVO.getInvoiceId());
         List<CrmReceivableDO> receivables = receivableMapper.selectListByInvoiceIdAndStatus(reqVO.getInvoiceId(),
@@ -240,9 +235,8 @@
         // 1.5 鏍¢獙鍙洖娆鹃噾棰濅笉瓒呰繃璇ュ紑绁ㄥ墿浣欏彲鍥炴閲戦
         validateReceivablePriceExceedsInvoiceRemaining(updateReqVO);
 
-        // 1.6 鍙湁鑽夌銆佸鎵逛腑锛屽彲浠ョ紪杈戯紱
-        if (!ObjectUtils.equalsAny(oldReceivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus(),
-                CrmAuditStatusEnum.PROCESS.getStatus())) {
+        // 1.6 鍙湁鏈鏍革紝鍙互缂栬緫锛�
+        if (ObjectUtil.notEqual(oldReceivable.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
             throw exception(RECEIVABLE_UPDATE_FAIL_EDITING_PROHIBITED);
         }
 
@@ -266,19 +260,22 @@
     }
 
     @Override
-    public void updateReceivableAuditStatus(Long id, Integer bpmResult) {
+    @Transactional(rollbackFor = Exception.class)
+    public void updateReceivableStatus(Long id, Integer status) {
+        boolean approve = CrmAuditStatusEnum.APPROVE.getStatus().equals(status);
         // 1.1 鏍¢獙瀛樺湪
         CrmReceivableDO receivable = validateReceivableExists(id);
-        // 1.2 鍙湁瀹℃壒涓紝鍙互鏇存柊瀹℃壒缁撴灉
-        if (ObjUtil.notEqual(receivable.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
-            log.error("[updateReceivableAuditStatus][receivable({}) 涓嶅浜庡鎵逛腑锛屾棤娉曟洿鏂板鎵圭粨鏋�({})]",
-                    receivable.getId(), bpmResult);
-            throw exception(RECEIVABLE_UPDATE_AUDIT_STATUS_FAIL_NOT_PROCESS);
+        // 1.2 鏍¢獙鐘舵��
+        if (receivable.getAuditStatus().equals(status)) {
+            throw exception(approve ? RECEIVABLE_APPROVE_FAIL : RECEIVABLE_PROCESS_FAIL);
         }
 
-        // 2. 鏇存柊鍥炴瀹℃壒鐘舵��
-        Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
-        receivableMapper.updateById(new CrmReceivableDO().setId(id).setAuditStatus(auditStatus));
+        // 2. 鏇存柊鐘舵��
+        int updateCount = receivableMapper.updateByIdAndStatus(id, receivable.getAuditStatus(),
+                new CrmReceivableDO().setAuditStatus(status));
+        if (updateCount == 0) {
+            throw exception(approve ? RECEIVABLE_APPROVE_FAIL : RECEIVABLE_PROCESS_FAIL);
+        }
     }
 
     @Override
@@ -306,29 +303,6 @@
         // 3. 璁板綍鎿嶄綔鏃ュ織涓婁笅鏂�
         LogRecordContext.putVariable("receivable", receivable);
         LogRecordContext.putVariable("period", getReceivablePeriod(receivable.getPlanId()));
-    }
-
-    @Override
-    @Transactional(rollbackFor = Exception.class)
-    @LogRecord(type = CRM_RECEIVABLE_TYPE, subType = CRM_RECEIVABLE_SUBMIT_SUB_TYPE, bizNo = "{{#id}}",
-            success = CRM_RECEIVABLE_SUBMIT_SUCCESS)
-    public void submitReceivable(Long id, Long userId) {
-        // 1. 鏍¢獙鍥炴鏄惁鍦ㄥ鎵�
-        CrmReceivableDO receivable = validateReceivableExists(id);
-        if (ObjUtil.notEqual(receivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) {
-            throw exception(RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT);
-        }
-
-        // 2. 鍒涘缓鍥炴瀹℃壒娴佺▼瀹炰緥
-        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
-                .setProcessDefinitionKey(BPM_PROCESS_DEFINITION_KEY).setBusinessKey(String.valueOf(id)));
-
-        // 3. 鏇存柊鍥炴宸ヤ綔娴佺紪鍙�
-        receivableMapper.updateById(new CrmReceivableDO().setId(id).setProcessInstanceId(processInstanceId)
-                .setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
-
-        // 4. 璁板綍鏃ュ織
-        LogRecordContext.putVariable("receivableNo", receivable.getNo());
     }
 
     private CrmReceivableDO validateReceivableExists(Long id) {

--
Gitblit v1.9.3