From 8168aef3c7557c9e1361892270a1ebe35dbddba5 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期二, 10 十一月 2026 11:42:19 +0800
Subject: [PATCH] refactor(erp): 采购申请与询价比价流程重构
---
yudao-module-srm/src/main/java/cn/iocoder/yudao/module/srm/service/inquiry/SrmInquiryServiceImpl.java | 136 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 136 insertions(+), 0 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 a750fba..2761cf4 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
@@ -11,8 +11,10 @@
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.ErpPurchaseRequestApi;
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderCreateReqDTO;
import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseOrderRespDTO;
+import cn.iocoder.yudao.module.erp.api.purchase.dto.ErpPurchaseRequestRespDTO;
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.api.unit.MdmUnitMeasureApi;
@@ -49,6 +51,11 @@
private static final DateTimeFormatter NO_DATE_FORMAT = DateTimeFormatter.ofPattern("yyyyMM");
+ /**
+ * 閲囪喘鐢宠銆屽鏍搁�氳繃銆嶇姸鎬佸�硷紝涓� ERP 妯″潡 ErpPurchaseRequestStatusEnum.APPROVE 淇濇寔涓�鑷�
+ */
+ private static final Integer PURCHASE_REQUEST_STATUS_APPROVED = 20;
+
@Resource
private SrmInquiryMapper inquiryMapper;
@Resource
@@ -69,6 +76,8 @@
private MdmUnitMeasureApi mdmUnitMeasureApi;
@Resource
private ErpPurchaseOrderApi erpPurchaseOrderApi;
+ @Resource
+ private ErpPurchaseRequestApi erpPurchaseRequestApi;
@Override
@Transactional(rollbackFor = Exception.class)
@@ -90,6 +99,73 @@
createReqVO.getSuppliers().stream()
.map(SrmInquirySaveReqVO.Supplier::getSupplierId)
.collect(Collectors.toSet()));
+ return inquiry.getId();
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long createInquiryFromPurchaseRequest(Long purchaseRequestId) {
+ ErpPurchaseRequestRespDTO purchaseRequest = erpPurchaseRequestApi
+ .getPurchaseRequest(purchaseRequestId).getCheckedData();
+ if (purchaseRequest == null) {
+ throw ServiceExceptionUtil.exception(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_NOT_EXISTS);
+ }
+ if (!PURCHASE_REQUEST_STATUS_APPROVED.equals(purchaseRequest.getStatus())) {
+ throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_NOT_APPROVED.getCode(),
+ "閲囪喘鐢宠銆�" + purchaseRequest.getNo() + "銆戝綋鍓嶇姸鎬佷笉鏄�屽鏍搁�氳繃銆嶏紝鏃犳硶鍙戣捣璇环銆�"
+ + "璇峰厛鍦ㄩ噰璐敵璇蜂腑瀹屾垚瀹℃壒锛屽鎵归�氳繃鍚庡啀鍙戣捣璇环銆�");
+ }
+ if (purchaseRequest.getOrderId() != null) {
+ throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_HAS_ORDER.getCode(),
+ "閲囪喘鐢宠銆�" + purchaseRequest.getNo() + "銆戝凡鐢熸垚閲囪喘鍙拌处銆�"
+ + StrUtil.blankToDefault(purchaseRequest.getOrderNo(), "ID=" + purchaseRequest.getOrderId())
+ + "銆戯紝鏃犳硶鍐嶅彂璧疯浠枫�傝鍒伴噰璐彴璐︿腑鏌ョ湅浠锋牸鏄庣粏銆�");
+ }
+ SrmInquiryDO linkedInquiry = purchaseRequest.getInquiryId() != null
+ ? inquiryMapper.selectById(purchaseRequest.getInquiryId()) : null;
+ if (linkedInquiry != null
+ && !InquiryStatusEnum.CANCELLED.getStatus().equals(linkedInquiry.getStatus())) {
+ throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_HAS_INQUIRY.getCode(),
+ "閲囪喘鐢宠銆�" + purchaseRequest.getNo() + "銆戝凡鍙戣捣杩囪浠枫��"
+ + StrUtil.blankToDefault(purchaseRequest.getInquiryNo(), "ID=" + purchaseRequest.getInquiryId())
+ + "銆戯紝璇风洿鎺ユ墦寮�璇ヨ浠峰崟缁х画澶勭悊锛屼笉瑕侀噸澶嶅彂璧枫��");
+ }
+ List<ErpPurchaseRequestRespDTO.Item> requestItems = purchaseRequest.getItems();
+ if (CollUtil.isEmpty(requestItems)) {
+ throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_ITEM_EMPTY.getCode(),
+ "閲囪喘鐢宠銆�" + purchaseRequest.getNo() + "銆戞病鏈夋槑缁嗚锛屾棤娉曞彂璧疯浠枫�傝鍥炲埌閲囪喘鐢宠琛ュ厖鏄庣粏鍚庡啀璇曘��");
+ }
+
+ SrmInquiryDO inquiry = new SrmInquiryDO();
+ inquiry.setNo(generateInquiryNo());
+ inquiry.setTitle("閲囪喘鐢宠銆�" + purchaseRequest.getNo() + "銆戣浠�");
+ inquiry.setStatus(InquiryStatusEnum.DRAFT.getStatus());
+ inquiry.setInquiryDate(LocalDate.now());
+ inquiry.setPurchaserUserId(getLoginUserId());
+ inquiry.setRemark("鐢遍噰璐敵璇枫��" + purchaseRequest.getNo() + "銆戝彂璧�");
+ inquiry.setPurchaseRequestId(purchaseRequest.getId());
+ inquiry.setPurchaseRequestNo(purchaseRequest.getNo());
+ inquiryMapper.insert(inquiry);
+
+ List<SrmInquirySaveReqVO.Item> itemVOs = new ArrayList<>();
+ Set<Long> productIds = new HashSet<>();
+ for (ErpPurchaseRequestRespDTO.Item requestItem : requestItems) {
+ if (!productIds.add(requestItem.getProductId())) {
+ throw new ServiceException(ErrorCodeConstants.INQUIRY_PURCHASE_REQUEST_ITEM_EMPTY.getCode(),
+ "閲囪喘鐢宠銆�" + purchaseRequest.getNo() + "銆戜腑浜у搧銆�"
+ + resolveItemName(requestItem.getProductId()) + "銆戝瓨鍦ㄥ琛屾槑缁嗭紝鏃犳硶鐩存帴鍙戣捣璇环銆�"
+ + "璇峰厛鍦ㄩ噰璐敵璇蜂腑鍚堝苟鍚屼竴浜у搧鐨勬暟閲忓悗鍐嶈瘯銆�");
+ }
+ SrmInquirySaveReqVO.Item itemVO = new SrmInquirySaveReqVO.Item();
+ itemVO.setProductId(requestItem.getProductId());
+ itemVO.setProductUnitId(requestItem.getProductUnitId());
+ itemVO.setQuantity(requestItem.getCount());
+ itemVO.setRemark(requestItem.getRemark());
+ itemVOs.add(itemVO);
+ }
+ saveItems(inquiry.getId(), itemVOs);
+
+ erpPurchaseRequestApi.updatePurchaseRequestInquiry(purchaseRequest.getId(), inquiry.getId(), inquiry.getNo());
return inquiry.getId();
}
@@ -139,6 +215,7 @@
inquirySupplierMapper.deleteByInquiryId(id);
inquiryQuoteMapper.deleteByInquiryId(id);
inquiryMapper.deleteById(id);
+ clearPurchaseRequestLink(inquiry);
}
@Override
@@ -235,6 +312,8 @@
}
inquiryMapper.updateById(new SrmInquiryDO()
.setId(id).setStatus(InquiryStatusEnum.CANCELLED.getStatus()));
+ // 璇环鍙栨秷鍚庤В闄ら噰璐敵璇峰叧鑱旓紝閲囪喘鍛樺彲閲嶆柊閫夋嫨銆屽彂璧疯浠枫�嶆垨銆岀洿鎺ョ敓鎴愬彴璐︺��
+ clearPurchaseRequestLink(inquiry);
}
@Override
@@ -458,6 +537,7 @@
createReqDTO.setSourceType(2);
createReqDTO.setSourceNo(inquiry.getNo());
createReqDTO.setSourceId(inquiry.getId());
+ createReqDTO.setPurchaseRequestId(inquiry.getPurchaseRequestId());
createReqDTO.setRemark("SRM璇环鑷姩鐢熸垚锛岃浠峰崟鍙凤細" + inquiry.getNo());
createReqDTO.setItems(orderItems);
@@ -490,6 +570,28 @@
orderResult.setPurchaseOrderId(purchaseOrderId);
orderResult.setPurchaseOrderNo(purchaseOrderNo);
orders.add(orderResult);
+ }
+
+ // 3.1 璇环鍗曟潵婧愪簬閲囪喘鐢宠鏃讹紝鍥炲啓閲囪喘鐢宠鍏宠仈鐨勯噰璐彴璐�
+ // 涓�涓浠峰崟鍙兘鎸変腑鏍囦緵搴斿晢鎷嗘垚澶氬紶鍙拌处锛岄噰璐敵璇峰彧璁板綍绗竴寮狅紝瀹屾暣娓呭崟鍙�氳繃鍙拌处鐨勯噰璐敵璇峰瓧娈靛弽鏌�
+ if (inquiry.getPurchaseRequestId() != null && CollUtil.isNotEmpty(orders)) {
+ SrmInquiryConfirmRespVO.Order firstOrder = orders.get(0);
+ if (orders.size() > 1) {
+ log.info("[confirmInquiry] 璇环鍗�({}) 涓洪噰璐敵璇�({}) 鐢熸垚 {} 寮犲彴璐︼紝閲囪喘鐢宠浠呭洖鍐欓寮犲彴璐�({})",
+ inquiry.getNo(), inquiry.getPurchaseRequestNo(), orders.size(), firstOrder.getPurchaseOrderNo());
+ }
+ try {
+ erpPurchaseRequestApi.updatePurchaseRequestOrder(inquiry.getPurchaseRequestId(),
+ firstOrder.getPurchaseOrderId(), firstOrder.getPurchaseOrderNo());
+ } catch (Exception ex) {
+ log.error("[confirmInquiry] 璇环鍗�({}) 鍥炲啓閲囪喘鐢宠({}) 鍏宠仈鍙拌处澶辫触",
+ inquiry.getNo(), inquiry.getPurchaseRequestNo(), ex);
+ throw new ServiceException(ErrorCodeConstants.INQUIRY_ORDER_GENERATE_FAIL.getCode(),
+ "璇环鍗曘��" + inquiry.getNo() + "銆戝凡鐢熸垚閲囪喘鍙拌处銆�"
+ + StrUtil.blankToDefault(firstOrder.getPurchaseOrderNo(), "ID=" + firstOrder.getPurchaseOrderId())
+ + "銆戯紝浣嗗洖鍐欓噰璐敵璇枫��" + inquiry.getPurchaseRequestNo() + "銆戝け璐ワ細" + ex.getMessage()
+ + "銆傝鍒伴噰璐敵璇蜂腑鏍稿鍏宠仈鍙拌处锛屾垨鑱旂郴绠$悊鍛樺鐞嗐��");
+ }
}
// 4. 鏇存柊璇环鍗曚负宸茶浆璁㈠崟锛堢姸鎬佹潯浠舵洿鏂帮紝閬垮厤骞跺彂閲嶅鐢熸垚锛�
@@ -726,6 +828,40 @@
"璇环鍗曞彿鍦ㄥ娆″皾璇曞悗浠嶉噸澶嶏紝璇风◢鍚庨噸璇曘��");
}
+ /**
+ * 璇环鍗曡鍙栨秷/鍒犻櫎鏃讹紝瑙i櫎瀵归噰璐敵璇风殑鍏宠仈锛岃閲囪喘鍛樺彲閲嶆柊閫夋嫨銆屽彂璧疯浠枫�嶆垨銆岀洿鎺ョ敓鎴愬彴璐︺�嶃��
+ * 瑙i櫎澶辫触鍙褰曟棩蹇楋紝涓嶉樆鏂彇娑堟搷浣滐紱鍙戣捣璇环鏃朵細鍐嶆寜璇环鍗曠姸鎬佸仛鍏滃簳鍒ゆ柇銆�
+ */
+ private void clearPurchaseRequestLink(SrmInquiryDO inquiry) {
+ if (inquiry.getPurchaseRequestId() == null) {
+ return;
+ }
+ try {
+ erpPurchaseRequestApi.clearPurchaseRequestInquiry(inquiry.getPurchaseRequestId());
+ } catch (Exception ex) {
+ log.warn("[clearPurchaseRequestLink] 璇环鍗�({}) 瑙i櫎閲囪喘鐢宠({}) 鍏宠仈澶辫触锛岃浜哄伐鏍稿",
+ inquiry.getNo(), inquiry.getPurchaseRequestNo(), ex);
+ }
+ }
+
+ /**
+ * 瑙f瀽浜у搧鍚嶇О锛屼粎鐢ㄤ簬寮傚父鎻愮ず锛涜В鏋愬け璐ユ椂鍥為��涓哄彲璇� ID锛岄伩鍏嶄簩娆″紓甯�
+ */
+ private String resolveItemName(Long productId) {
+ if (productId == null) {
+ return "鏈�夋嫨";
+ }
+ try {
+ MdmItemRespDTO item = mdmItemApi.getItem(productId).getCheckedData();
+ if (item != null && StrUtil.isNotBlank(item.getName())) {
+ return item.getName();
+ }
+ } catch (Exception ex) {
+ log.warn("[resolveItemName] 鏌ヨ浜у搧({}) 鍚嶇О澶辫触", productId, ex);
+ }
+ return "ID=" + productId;
+ }
+
private String statusName(Integer status) {
for (InquiryStatusEnum e : InquiryStatusEnum.values()) {
if (e.getStatus().equals(status)) {
--
Gitblit v1.9.3