From d39e4f7d839167c16425086dfa2f8747bccfdff9 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 05 十一月 2026 17:39:01 +0800
Subject: [PATCH] feat: 打通销售采购财务闭环并完成累计业务优化
---
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java | 118 ++++++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 93 insertions(+), 25 deletions(-)
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
index 408d6d6..995c361 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/service/finance/ErpFinancePaymentServiceImpl.java
@@ -2,8 +2,11 @@
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.erp.api.finance.dto.ErpFinancePaymentRedFlushCreateReqDTO;
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.dal.dataobject.definition.BpmCategoryDO;
@@ -20,7 +23,8 @@
import cn.iocoder.yudao.module.erp.dal.mysql.finance.ErpFinancePaymentMapper;
import cn.iocoder.yudao.module.erp.dal.redis.no.ErpNoRedisDAO;
import cn.iocoder.yudao.module.erp.enums.ErpAuditStatus;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
+import cn.iocoder.yudao.module.erp.enums.common.ErpBizTypeEnum;
+import cn.iocoder.yudao.module.erp.enums.finance.ErpFinancePaymentSourceTypeEnum;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl;
import cn.iocoder.yudao.module.erp.service.purchase.ErpSupplierService;
@@ -34,6 +38,7 @@
import org.springframework.validation.annotation.Validated;
import java.math.BigDecimal;
+import java.time.LocalDateTime;
import java.util.*;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@@ -66,8 +71,6 @@
@Resource
private ErpSupplierService supplierService;
@Resource
- private ErpAccountService accountService;
- @Resource
private ErpPurchaseInvoiceService invoiceService;
@Resource
@@ -91,17 +94,13 @@
createReqVO.getSupplierId(), createReqVO.getItems());
// 1.2 鏍¢獙渚涘簲鍟�
supplierService.validateSupplier(createReqVO.getSupplierId());
- // 1.3 鏍¢獙缁撶畻璐︽埛
- if (createReqVO.getAccountId() != null) {
- accountService.validateAccount(createReqVO.getAccountId());
- }
- // 1.4 鏍¢獙璐㈠姟浜哄憳
+ // 1.3 鏍¢獙璐㈠姟浜哄憳
if (createReqVO.getFinanceUserId() != null) {
adminUserApi.validateUser(createReqVO.getFinanceUserId());
}
- // 1.5 鏍¢獙鍏宠仈鏉ョエ
+ // 1.4 鏍¢獙鍏宠仈鏉ョエ
validateInvoiceForPayment(createReqVO.getInvoiceId(), createReqVO.getSupplierId());
- // 1.6 鏍¢獙浠樻閲戦涓嶈秴杩囪鏉ョエ鍓╀綑鍙粯閲戦
+ // 1.5 鏍¢獙浠樻閲戦涓嶈秴杩囪鏉ョエ鍓╀綑鍙粯閲戦
validatePaymentPriceExceedsInvoiceRemaining(createReqVO.getInvoiceId(),
getSumValue(paymentItems, ErpFinancePaymentItemDO::getPaymentPrice, BigDecimal::add, BigDecimal.ZERO)
.subtract(createReqVO.getDiscountPrice()), null);
@@ -142,20 +141,16 @@
}
// 1.2 鏍¢獙渚涘簲鍟�
supplierService.validateSupplier(updateReqVO.getSupplierId());
- // 1.3 鏍¢獙缁撶畻璐︽埛
- if (updateReqVO.getAccountId() != null) {
- accountService.validateAccount(updateReqVO.getAccountId());
- }
- // 1.4 鏍¢獙璐㈠姟浜哄憳
+ // 1.3 鏍¢獙璐㈠姟浜哄憳
if (updateReqVO.getFinanceUserId() != null) {
adminUserApi.validateUser(updateReqVO.getFinanceUserId());
}
- // 1.5 鏍¢獙浠樻鍗曢」鐨勬湁鏁堟��
+ // 1.4 鏍¢獙浠樻鍗曢」鐨勬湁鏁堟��
List<ErpFinancePaymentItemDO> paymentItems = validateFinancePaymentItems(
updateReqVO.getSupplierId(), updateReqVO.getItems());
- // 1.6 鏍¢獙鍏宠仈鏉ョエ
+ // 1.5 鏍¢獙鍏宠仈鏉ョエ
validateInvoiceForPayment(updateReqVO.getInvoiceId(), updateReqVO.getSupplierId());
- // 1.7 鏍¢獙浠樻閲戦涓嶈秴杩囪鏉ョエ鍓╀綑鍙粯閲戦锛堟帓闄よ浠樻鍗曡嚜韬綋鍓嶅凡浠橀噾棰濓級
+ // 1.6 鏍¢獙浠樻閲戦涓嶈秴杩囪鏉ョエ鍓╀綑鍙粯閲戦锛堟帓闄よ浠樻鍗曡嚜韬綋鍓嶅凡浠橀噾棰濓級
validatePaymentPriceExceedsInvoiceRemaining(updateReqVO.getInvoiceId(),
getSumValue(paymentItems, ErpFinancePaymentItemDO::getPaymentPrice, BigDecimal::add, BigDecimal.ZERO)
.subtract(updateReqVO.getDiscountPrice()), payment.getPaymentPrice());
@@ -185,6 +180,16 @@
}
// 2. 鍒涘缓 BPM 娴佺▼瀹炰緥
+ // 鍏ㄥ眬鍏嶅鎵癸細涓氬姟鏍¢獙閫氳繃鍚庣洿鎺ユ墽琛屽鎵归�氳繃閫昏緫锛屾棤闇�娴佺▼妯″瀷銆�
+ if (processInstanceApi.isGlobalAutoApprove()) {
+ financePaymentMapper.updateById(new ErpFinancePaymentDO()
+ .setId(id)
+ .setStatus(ErpAuditStatus.APPROVING.getStatus())
+ .setProcessInstanceId(""));
+ updateFinancePaymentAuditStatus(id, cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceStatusEnum.APPROVE.getStatus());
+ return;
+ }
+
String processInstanceId = processInstanceApi.createProcessInstance(userId,
new BpmProcessInstanceCreateReqDTO()
.setProcessDefinitionKey(processDefinitionKey)
@@ -354,7 +359,7 @@
}
/**
- * 鏍¢獙浠樻鍗曞叧鑱旂殑鏉ョエ锛氬瓨鍦ㄣ�佸鎵归�氳繃銆佸凡涓婁紶鍙戠エ闄勪欢銆佷緵搴斿晢涓庢潵绁ㄤ竴鑷�
+ * 鏍¢獙浠樻鍗曞叧鑱旂殑鏉ョエ锛氬瓨鍦ㄣ�佸凡涓婁紶鍙戠エ闄勪欢銆佷緵搴斿晢涓庢潵绁ㄤ竴鑷�
*
* @param invoiceId 鏉ョエ缂栧彿
* @param supplierId 渚涘簲鍟嗙紪鍙�
@@ -365,16 +370,12 @@
if (invoice == null) {
throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_EXISTS);
}
- // 2. 鏍¢獙鏉ョエ瀹℃壒閫氳繃
- if (ObjectUtil.notEqual(invoice.getAuditStatus(), ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus())) {
- throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_APPROVE);
- }
- // 3. 鏍¢獙宸蹭笂浼犲彂绁ㄩ檮浠�
+ // 2. 鏍¢獙宸蹭笂浼犲彂绁ㄩ檮浠�
if (CollUtil.isEmpty(storageAttachmentApi.listAttachments(
ErpPurchaseInvoiceServiceImpl.PURCHASE_INVOICE_RECORD_TYPE, invoiceId))) {
throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_NOT_ATTACHMENT);
}
- // 4. 鏍¢獙渚涘簲鍟嗕笌鏉ョエ涓�鑷达紙闃茶剰鏁版嵁锛�
+ // 3. 鏍¢獙渚涘簲鍟嗕笌鏉ョエ涓�鑷达紙闃茶剰鏁版嵁锛�
if (ObjectUtil.notEqual(invoice.getSupplierId(), supplierId)) {
throw exception(FINANCE_PAYMENT_CREATE_FAIL_INVOICE_SUPPLIER_MISMATCH);
}
@@ -401,6 +402,73 @@
}
@Override
+ @Transactional(rollbackFor = Exception.class)
+ public Long createRedFlushPayment(ErpFinancePaymentRedFlushCreateReqDTO reqDTO) {
+ // 1.1 鏍¢獙鏉ユ簮鍗曟嵁锛氬啿绾㈠崟蹇呴』鑳借拷婧埌閫�璐у崟
+ if (reqDTO.getSourceId() == null || StrUtil.isBlank(reqDTO.getSourceNo())) {
+ throw exception(FINANCE_PAYMENT_RED_FLUSH_SOURCE_REQUIRED);
+ }
+ // 1.2 鏍¢獙渚涘簲鍟�
+ if (reqDTO.getSupplierId() == null) {
+ throw exception(FINANCE_PAYMENT_RED_FLUSH_SUPPLIER_REQUIRED);
+ }
+ supplierService.validateSupplier(reqDTO.getSupplierId());
+ // 1.3 鏍¢獙閫�娆鹃噾棰�
+ if (reqDTO.getRefundAmount() == null || reqDTO.getRefundAmount().compareTo(BigDecimal.ZERO) <= 0) {
+ throw exception(FINANCE_PAYMENT_RED_FLUSH_AMOUNT_INVALID, reqDTO.getRefundAmount());
+ }
+ // 1.4 鏍¢獙璐㈠姟浜哄憳
+ if (reqDTO.getFinanceUserId() != null) {
+ adminUserApi.validateUser(reqDTO.getFinanceUserId());
+ }
+ // 1.5 骞傜瓑锛氬悓涓�鏉ユ簮閫�璐у崟鍙厑璁哥敓鎴愪竴寮犲啿绾㈠崟
+ ErpFinancePaymentDO existing = financePaymentMapper.selectOne(new LambdaQueryWrapperX<ErpFinancePaymentDO>()
+ .eq(ErpFinancePaymentDO::getSourceType,
+ ErpFinancePaymentSourceTypeEnum.PURCHASE_RETURN_RED_FLUSH.getType())
+ .eq(ErpFinancePaymentDO::getSourceId, reqDTO.getSourceId()));
+ if (existing != null) {
+ log.info("[createRedFlushPayment][閫�璐у崟({}) 宸插瓨鍦ㄥ啿绾㈠崟({})锛岀洿鎺ュ鐢╙",
+ reqDTO.getSourceNo(), existing.getNo());
+ return existing.getId();
+ }
+
+ // 2.1 鐢熸垚浠樻鍗曞彿
+ String no = noRedisDAO.generate(ErpNoRedisDAO.FINANCE_PAYMENT_NO_PREFIX);
+ if (financePaymentMapper.selectByNo(no) != null) {
+ throw exception(FINANCE_PAYMENT_NO_EXISTS);
+ }
+ // 2.2 閲戦鎸夎礋鏁板叆璐�
+ BigDecimal negativeAmount = reqDTO.getRefundAmount().negate();
+ ErpFinancePaymentDO payment = new ErpFinancePaymentDO()
+ .setNo(no)
+ .setStatus(ErpAuditStatus.APPROVE.getStatus())
+ .setPaymentTime(LocalDateTime.now())
+ .setFinanceUserId(reqDTO.getFinanceUserId())
+ .setSupplierId(reqDTO.getSupplierId())
+ .setAccountName(reqDTO.getAccountName())
+ .setTotalPrice(negativeAmount)
+ .setDiscountPrice(BigDecimal.ZERO)
+ .setPaymentPrice(negativeAmount)
+ .setRemark(StrUtil.blankToDefault(reqDTO.getRemark(), "閲囪喘閫�璐у啿绾�"))
+ .setSourceType(ErpFinancePaymentSourceTypeEnum.PURCHASE_RETURN_RED_FLUSH.getType())
+ .setSourceId(reqDTO.getSourceId())
+ .setSourceNo(reqDTO.getSourceNo());
+ financePaymentMapper.insert(payment);
+
+ // 3. 鎻掑叆浠樻椤癸紙涓氬姟绫诲瀷锛氶噰璐��璐э級
+ financePaymentItemMapper.insert(new ErpFinancePaymentItemDO()
+ .setPaymentId(payment.getId())
+ .setBizType(ErpBizTypeEnum.PURCHASE_RETURN.getType())
+ .setBizId(reqDTO.getSourceId())
+ .setBizNo(reqDTO.getSourceNo())
+ .setTotalPrice(negativeAmount)
+ .setPaidPrice(BigDecimal.ZERO)
+ .setPaymentPrice(negativeAmount)
+ .setRemark(StrUtil.blankToDefault(reqDTO.getRemark(), "閲囪喘閫�璐у啿绾�")));
+ return payment.getId();
+ }
+
+ @Override
public ErpFinancePaymentDO getFinancePayment(Long id) {
return financePaymentMapper.selectById(id);
}
--
Gitblit v1.9.3