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/receivable/CrmReceivableServiceImpl.java | 106 +++++++++++++++++++++++++++++------------------------
1 files changed, 58 insertions(+), 48 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..2a6d218 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;
@@ -27,7 +24,11 @@
import cn.iocoder.yudao.module.crm.service.invoice.CrmInvoiceService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionCreateReqBO;
+import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
+import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
+import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum;
import cn.iocoder.yudao.module.system.api.storage.StorageAttachmentApi;
+import cn.iocoder.yudao.module.system.api.approval.ApprovalConfigApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.enums.storage.StorageRecordTypeEnum;
import com.mzt.logapi.context.LogRecordContext;
@@ -44,9 +45,9 @@
import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
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 瀹炵幇绫�
@@ -58,10 +59,8 @@
@Slf4j
public class CrmReceivableServiceImpl implements CrmReceivableService {
- /**
- * BPM 鍚堝悓瀹℃壒娴佺▼鏍囪瘑
- */
- public static final String BPM_PROCESS_DEFINITION_KEY = "crm-receivable-audit";
+ private static final String RECEIVABLE_PROCESS_KEY = "crm-receivable-audit";
+ private static final String RECEIVABLE_APPROVE_BIZ_TYPE = "crm_receivable_approve";
@Resource
private CrmReceivableMapper receivableMapper;
@@ -82,9 +81,11 @@
@Resource
private AdminUserApi adminUserApi;
@Resource
+ private StorageAttachmentApi storageAttachmentApi;
+ @Resource
private BpmProcessInstanceApi bpmProcessInstanceApi;
@Resource
- private StorageAttachmentApi storageAttachmentApi;
+ private ApprovalConfigApi approvalConfigApi;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -105,7 +106,7 @@
throw exception(RECEIVABLE_NO_EXISTS);
}
- // 2.1 鎻掑叆鍥炴
+ // 2.1 鎻掑叆鑽夌锛涙彁浜ゆ椂鍐嶅垱寤� BPM 娴佺▼
CrmReceivableDO receivable = BeanUtils.toBean(createReqVO, CrmReceivableDO.class)
.setNo(no).setAuditStatus(CrmAuditStatusEnum.DRAFT.getStatus());
receivableMapper.insert(receivable);
@@ -240,9 +241,9 @@
// 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.DRAFT.getStatus())
+ && ObjectUtil.notEqual(oldReceivable.getAuditStatus(), CrmAuditStatusEnum.REJECT.getStatus())) {
throw exception(RECEIVABLE_UPDATE_FAIL_EDITING_PROHIBITED);
}
@@ -266,19 +267,50 @@
}
@Override
- public void updateReceivableAuditStatus(Long id, Integer bpmResult) {
- // 1.1 鏍¢獙瀛樺湪
+ @Transactional(rollbackFor = Exception.class)
+ @CrmPermission(bizType = CrmBizTypeEnum.CRM_RECEIVABLE, bizId = "#id", level = CrmPermissionLevelEnum.WRITE)
+ public void submitReceivable(Long id) {
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);
+ if (ObjectUtil.notEqual(receivable.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())
+ && ObjectUtil.notEqual(receivable.getAuditStatus(), CrmAuditStatusEnum.REJECT.getStatus())) {
+ throw exception(RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT);
}
+ // 鑽夌鏈熷彲鑳藉凡浜х敓鍏朵粬鍥炴锛屾彁浜ゆ椂閲嶆柊鏍¢獙鍚堝悓鍙婂紑绁ㄩ搴︺��
+ CrmReceivableSaveReqVO req = new CrmReceivableSaveReqVO().setId(id)
+ .setContractId(receivable.getContractId()).setInvoiceId(receivable.getInvoiceId())
+ .setCustomerId(receivable.getCustomerId()).setPrice(receivable.getPrice());
+ validateInvoiceForReceivable(req);
+ validateReceivablePriceExceedsLimit(req);
+ validateReceivablePriceExceedsInvoiceRemaining(req);
+ approvalConfigApi.validateApprovalEnabledAndGetApprovers(RECEIVABLE_APPROVE_BIZ_TYPE);
+ int updateCount = receivableMapper.updateByIdAndStatus(id, receivable.getAuditStatus(),
+ new CrmReceivableDO().setAuditStatus(CrmAuditStatusEnum.PROCESS.getStatus()));
+ if (updateCount == 0) {
+ throw exception(RECEIVABLE_SUBMIT_FAIL_NOT_DRAFT);
+ }
+ String processInstanceId = bpmProcessInstanceApi.createProcessInstance(getLoginUserId(),
+ new BpmProcessInstanceCreateReqDTO().setProcessDefinitionKey(RECEIVABLE_PROCESS_KEY)
+ .setBusinessKey(String.valueOf(id)));
+ receivableMapper.updateById(new CrmReceivableDO().setId(id).setProcessInstanceId(processInstanceId));
+ }
- // 2. 鏇存柊鍥炴瀹℃壒鐘舵��
- Integer auditStatus = convertBpmResultToAuditStatus(bpmResult);
- receivableMapper.updateById(new CrmReceivableDO().setId(id).setAuditStatus(auditStatus));
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void updateReceivableAuditStatus(Long id, Integer bpmStatus) {
+ Integer auditStatus;
+ if (BpmTaskStatusEnum.APPROVE.getStatus().equals(bpmStatus)) {
+ auditStatus = CrmAuditStatusEnum.APPROVE.getStatus();
+ } else if (BpmTaskStatusEnum.REJECT.getStatus().equals(bpmStatus)) {
+ auditStatus = CrmAuditStatusEnum.REJECT.getStatus();
+ } else if (BpmTaskStatusEnum.CANCEL.getStatus().equals(bpmStatus)) {
+ auditStatus = CrmAuditStatusEnum.CANCEL.getStatus();
+ } else {
+ return;
+ }
+ if (receivableMapper.updateByIdAndStatus(id, CrmAuditStatusEnum.PROCESS.getStatus(),
+ new CrmReceivableDO().setAuditStatus(auditStatus)) != 1) {
+ log.warn("[updateReceivableAuditStatus] 鍥炴({}) 宸蹭笉澶勪簬瀹℃壒涓紝蹇界暐 BPM 鐘舵��({})", id, bpmStatus);
+ }
}
@Override
@@ -293,8 +325,9 @@
if (receivable.getPlanId() != null && receivablePlanService.getReceivablePlan(receivable.getPlanId()) != null) {
throw exception(RECEIVABLE_DELETE_FAIL);
}
- // 1.3 瀹℃壒閫氳繃鏃讹紝涓嶅厑璁稿垹闄�
- if (ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())) {
+ // 瀹℃壒涓�佸鏍搁�氳繃涓嶅彲鍒犻櫎
+ if (ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.APPROVE.getStatus())
+ || ObjUtil.equal(receivable.getAuditStatus(), CrmAuditStatusEnum.PROCESS.getStatus())) {
throw exception(RECEIVABLE_DELETE_FAIL_IS_APPROVE);
}
@@ -306,29 +339,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