From ccdebc5369c108e6616550bfbe1cd47ec1e05813 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期一, 09 十一月 2026 11:44:31 +0800
Subject: [PATCH] feat(bpm): 接入询价单与项目用印审批流程

---
 yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/inquiry/SrmInquiryServiceImpl.java |   90 +++++++++++++++++++++++++++++++++++++-------
 1 files changed, 75 insertions(+), 15 deletions(-)

diff --git a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/inquiry/SrmInquiryServiceImpl.java b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/inquiry/SrmInquiryServiceImpl.java
index 98f25c5..a750fba 100644
--- a/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/inquiry/SrmInquiryServiceImpl.java
+++ b/yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/inquiry/SrmInquiryServiceImpl.java
@@ -7,6 +7,9 @@
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+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.BpmProcessInstanceStatusEnum;
 import cn.iocoder.yudao.module.erp.api.purchase.ErpPurchaseOrderApi;
 import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderCreateReqDTO;
 import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO;
@@ -48,6 +51,8 @@
 
     @Resource
     private SrmInquiryMapper inquiryMapper;
+    @Resource
+    private BpmProcessInstanceApi processInstanceApi;
     @Resource
     private SrmInquiryItemMapper inquiryItemMapper;
     @Resource
@@ -91,8 +96,9 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void updateInquiry(SrmInquirySaveReqVO updateReqVO) {
-        SrmInquiryDO inquiry = validateInquiryExists(updateReqVO.getId());
-        if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())) {
+        SrmInquiryDO inquiry = validateInquiryForUpdate(updateReqVO.getId());
+        if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())
+                && !InquiryStatusEnum.REJECTED.getStatus().equals(inquiry.getStatus())) {
             throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_EDITABLE.getCode(),
                     "璇环鍗曘��" + inquiry.getNo() + "銆戝綋鍓嶇姸鎬佷负銆�" + statusName(inquiry.getStatus())
                             + "銆戯紝浠呰崏绋跨姸鎬佸彲缂栬緫銆傚闇�璋冩暣浜у搧琛屾垨渚涘簲鍟嗭紝璇峰彇娑堝悗閲嶆柊鍒涘缓璇环鍗曘��");
@@ -123,7 +129,7 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void deleteInquiry(Long id) {
-        SrmInquiryDO inquiry = validateInquiryExists(id);
+        SrmInquiryDO inquiry = validateInquiryForUpdate(id);
         if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())) {
             throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_EDITABLE.getCode(),
                     "璇环鍗曘��" + inquiry.getNo() + "銆戝綋鍓嶇姸鎬佷负銆�" + statusName(inquiry.getStatus())
@@ -161,8 +167,52 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    public void submitApproval(Long id, Long userId) {
+        SrmInquiryDO inquiry = validateInquiryForUpdate(id);
+        if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())
+                && !InquiryStatusEnum.QUOTING.getStatus().equals(inquiry.getStatus())
+                && !InquiryStatusEnum.REJECTED.getStatus().equals(inquiry.getStatus())) {
+            throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_CONFIRMABLE.getCode(), "褰撳墠鐘舵�佷笉鍙彁浜ゅ鏍�");
+        }
+        List<SrmInquiryItemDO> items = inquiryItemMapper.selectListByInquiryId(id);
+        if (CollUtil.isEmpty(items)) throw ServiceExceptionUtil.exception(ErrorCodeConstants.INQUIRY_ITEM_EMPTY);
+        Map<Long, SrmInquiryQuoteDO> quotes = inquiryQuoteMapper.selectListByInquiryId(id).stream()
+                .collect(Collectors.toMap(SrmInquiryQuoteDO::getId, Function.identity()));
+        Set<Long> suppliers = inquirySupplierMapper.selectListByInquiryId(id).stream()
+                .map(SrmInquirySupplierDO::getSupplierId).collect(Collectors.toSet());
+        for (SrmInquiryItemDO item : items) {
+            SrmInquiryQuoteDO quote = quotes.get(item.getSelectedQuoteId());
+            if (quote == null || !item.getId().equals(quote.getInquiryItemId())
+                    || !suppliers.contains(quote.getSupplierId()) || quote.getPrice() == null
+                    || quote.getPrice().compareTo(BigDecimal.ZERO) <= 0) {
+                throw new ServiceException(ErrorCodeConstants.INQUIRY_WINNER_REQUIRED.getCode(), "璇峰厛涓烘瘡涓骇鍝侀�夋嫨鏈夋晥鐨勪腑鏍囨姤浠�");
+            }
+            inquiryItemMapper.updateById(new SrmInquiryItemDO().setId(item.getId())
+                    .setSelectedSupplierId(quote.getSupplierId()).setSelectedPrice(quote.getPrice()));
+        }
+        inquiryMapper.updateById(new SrmInquiryDO().setId(id).setStatus(InquiryStatusEnum.APPROVING.getStatus()).setProcessInstanceId(""));
+        String processId = processInstanceApi.createProcessInstance(userId, new BpmProcessInstanceCreateReqDTO()
+                .setProcessDefinitionKey("srm_inquiry_approve").setBusinessKey(String.valueOf(id))
+                .setVariables(Map.of("inquiryNo", inquiry.getNo(), "inquiryTitle", inquiry.getTitle())));
+        inquiryMapper.updateById(new SrmInquiryDO().setId(id).setProcessInstanceId(processId));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateApprovalStatus(Long id, String processInstanceId, Integer status) {
+        SrmInquiryDO inquiry = validateInquiryForUpdate(id);
+        if (!InquiryStatusEnum.APPROVING.getStatus().equals(inquiry.getStatus())
+                || (StrUtil.isNotEmpty(inquiry.getProcessInstanceId()) && !Objects.equals(inquiry.getProcessInstanceId(), processInstanceId))) return;
+        Integer next = null;
+        if (BpmProcessInstanceStatusEnum.APPROVE.getStatus().equals(status)) next = InquiryStatusEnum.APPROVED.getStatus();
+        if (BpmProcessInstanceStatusEnum.REJECT.getStatus().equals(status) || BpmProcessInstanceStatusEnum.CANCEL.getStatus().equals(status)) next = InquiryStatusEnum.REJECTED.getStatus();
+        if (next != null) inquiryMapper.updateById(new SrmInquiryDO().setId(id).setStatus(next));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
     public void publishInquiry(Long id) {
-        SrmInquiryDO inquiry = validateInquiryExists(id);
+        SrmInquiryDO inquiry = validateInquiryForUpdate(id);
         if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())) {
             throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_QUOTING.getCode(),
                     "璇环鍗曘��" + inquiry.getNo() + "銆戝綋鍓嶇姸鎬佷负銆�" + statusName(inquiry.getStatus())
@@ -175,9 +225,10 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void cancelInquiry(Long id) {
-        SrmInquiryDO inquiry = validateInquiryExists(id);
+        SrmInquiryDO inquiry = validateInquiryForUpdate(id);
         if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())
-                && !InquiryStatusEnum.QUOTING.getStatus().equals(inquiry.getStatus())) {
+                && !InquiryStatusEnum.QUOTING.getStatus().equals(inquiry.getStatus())
+                && !InquiryStatusEnum.REJECTED.getStatus().equals(inquiry.getStatus())) {
             throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_CANCELLABLE.getCode(),
                     "璇环鍗曘��" + inquiry.getNo() + "銆戝綋鍓嶇姸鎬佷负銆�" + statusName(inquiry.getStatus())
                             + "銆戯紝浠呰崏绋挎垨璇环涓姸鎬佸彲鍙栨秷銆�");
@@ -189,9 +240,10 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void saveQuotes(SrmInquiryQuoteSaveReqVO saveReqVO) {
-        SrmInquiryDO inquiry = validateInquiryExists(saveReqVO.getInquiryId());
+        SrmInquiryDO inquiry = validateInquiryForUpdate(saveReqVO.getInquiryId());
         if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())
-                && !InquiryStatusEnum.QUOTING.getStatus().equals(inquiry.getStatus())) {
+                && !InquiryStatusEnum.QUOTING.getStatus().equals(inquiry.getStatus())
+                && !InquiryStatusEnum.REJECTED.getStatus().equals(inquiry.getStatus())) {
             throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_QUOTING.getCode(),
                     "璇环鍗曘��" + inquiry.getNo() + "銆戝綋鍓嶇姸鎬佷负銆�" + statusName(inquiry.getStatus())
                             + "銆戯紝浠呰崏绋挎垨璇环涓姸鎬佸彲褰曞叆鎶ヤ环銆�");
@@ -269,12 +321,12 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public SrmInquiryConfirmRespVO confirmInquiry(SrmInquiryConfirmReqVO confirmReqVO) {
-        SrmInquiryDO inquiry = validateInquiryExists(confirmReqVO.getId());
-        if (!InquiryStatusEnum.DRAFT.getStatus().equals(inquiry.getStatus())
-                && !InquiryStatusEnum.QUOTING.getStatus().equals(inquiry.getStatus())) {
-            throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_CONFIRMABLE.getCode(),
-                    "璇环鍗曘��" + inquiry.getNo() + "銆戝綋鍓嶇姸鎬佷负銆�" + statusName(inquiry.getStatus())
-                            + "銆戯紝浠呰崏绋挎垨璇环涓姸鎬佸彲纭杞鍗曘��");
+        SrmInquiryDO inquiry = validateInquiryForUpdate(confirmReqVO.getId());
+        if (!InquiryStatusEnum.APPROVED.getStatus().equals(inquiry.getStatus())) {
+            throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_CONFIRMABLE.getCode(), "璇环鍗曞鏍搁�氳繃鍚庢墠鑳借浆璁㈠崟");
+        }
+        if (CollUtil.isNotEmpty(confirmReqVO.getSelections())) {
+            throw new ServiceException(ErrorCodeConstants.INQUIRY_STATUS_NOT_CONFIRMABLE.getCode(), "瀹℃牳閫氳繃鍚庝笉鑳芥洿鏀逛腑鏍囩粨鏋�");
         }
         List<SrmInquiryItemDO> items = inquiryItemMapper.selectListByInquiryId(inquiry.getId());
         if (CollUtil.isEmpty(items)) {
@@ -393,12 +445,14 @@
                 orderItem.setCount(item.getQuantity());
                 orderItem.setTaxPercent(quote.getTaxRate());
                 orderItem.setRemark("SRM璇环 " + inquiry.getNo());
-                orderItem.setQcCheckFlag(false);
+                // 涓庨噰璐敵璇�/閲囪喘鍙拌处涓�鑷达細鏂扮敓鎴愮殑閲囪喘鏄庣粏榛樿璐ㄦ
+                orderItem.setQcCheckFlag(true);
                 orderItems.add(orderItem);
             }
             ErpPurchaseOrderCreateReqDTO createReqDTO = new ErpPurchaseOrderCreateReqDTO();
             createReqDTO.setSupplierId(supplierId);
             createReqDTO.setOrderTime(LocalDateTime.now());
+            createReqDTO.setPaymentDate(confirmReqVO.getPaymentDate().atStartOfDay());
             createReqDTO.setDiscountPercent(BigDecimal.ZERO);
             createReqDTO.setDepositPrice(BigDecimal.ZERO);
             createReqDTO.setSourceType(2);
@@ -645,6 +699,12 @@
 
     // ========== 鏍¢獙 ==========
 
+    private SrmInquiryDO validateInquiryForUpdate(Long id) {
+        SrmInquiryDO inquiry = inquiryMapper.selectByIdForUpdate(id);
+        if (inquiry == null) throw ServiceExceptionUtil.exception(ErrorCodeConstants.INQUIRY_NOT_EXISTS);
+        return inquiry;
+    }
+
     private SrmInquiryDO validateInquiryExists(Long id) {
         SrmInquiryDO inquiry = inquiryMapper.selectById(id);
         if (inquiry == null) {

--
Gitblit v1.9.3