From 3688f07fd292812994dbf3c84bde18a440d8275c Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 04 十一月 2026 16:52:29 +0800
Subject: [PATCH] feat(erp): 采购来票支持关联多张采购订单并按订单分摊金额
---
yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java | 92 ++++++++++++++++++++++++++++++++-------------
1 files changed, 65 insertions(+), 27 deletions(-)
diff --git a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
index 8d00f34..3f26dad 100644
--- a/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
+++ b/yudao-module-erp/src/main/java/cn/iocoder/yudao/module/erp/controller/admin/purchase/ErpPurchaseInvoiceController.java
@@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.erp.controller.admin.purchase;
import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -9,13 +10,14 @@
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceOrderRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoicePageReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceRespVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.invoice.ErpPurchaseInvoiceSaveReqVO;
import cn.iocoder.yudao.module.erp.controller.admin.purchase.vo.order.ErpPurchaseOrderRespVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceDO;
+import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseInvoiceOrderDO;
import cn.iocoder.yudao.module.erp.dal.dataobject.purchase.ErpPurchaseOrderDO;
-import cn.iocoder.yudao.module.erp.enums.ErpPurchaseInvoiceAuditStatusEnum;
import cn.iocoder.yudao.module.erp.service.finance.ErpFinancePaymentService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceService;
import cn.iocoder.yudao.module.erp.service.purchase.ErpPurchaseInvoiceServiceImpl;
@@ -39,14 +41,17 @@
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
+import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
@@ -139,10 +144,33 @@
Map<Long, SrmSupplierRespDTO> supplierMap = srmSupplierApi.getSupplierList(
convertSet(invoiceList, ErpPurchaseInvoiceDO::getSupplierId)).getCheckedData().stream()
.collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a));
- // 1.2 鑾峰彇閲囪喘璁㈠崟鍒楄〃
+ // 1.2 鑾峰彇閲囪喘璁㈠崟鍒嗘憡鏄庣粏锛堜竴寮犳潵绁ㄥ彲鍏宠仈澶氬紶璁㈠崟锛�
+ Map<Long, List<ErpPurchaseInvoiceOrderDO>> allocationMap = convertMultiMap(
+ invoiceService.getPurchaseInvoiceOrderListByInvoiceIds(
+ convertSet(invoiceList, ErpPurchaseInvoiceDO::getId)),
+ ErpPurchaseInvoiceOrderDO::getInvoiceId);
+ // 1.2.1 鍏煎鍘嗗彶鏁版嵁锛氭病鏈夊垎鎽婃槑缁嗙殑鏉ョエ锛屾寜涓昏鍗� + 鏉ョエ閲戦瑙嗕负涓�鏉″垎鎽�
+ for (ErpPurchaseInvoiceDO invoice : invoiceList) {
+ if (!allocationMap.containsKey(invoice.getId()) && invoice.getPurchaseOrderId() != null) {
+ allocationMap.put(invoice.getId(), Collections.singletonList(
+ ErpPurchaseInvoiceOrderDO.builder().invoiceId(invoice.getId())
+ .purchaseOrderId(invoice.getPurchaseOrderId()).price(invoice.getPrice()).sort(0).build()));
+ }
+ }
+ // 1.2.2 杩欎簺璁㈠崟鐨勫叏閮ㄥ垎鎽婃槑缁嗭紝鐢ㄤ簬璁$畻姣忓紶璁㈠崟銆屽叾浠栨潵绁ㄥ凡鍗犵敤閲戦銆�
+ Set<Long> orderIds = convertSet(allocationMap.values().stream().flatMap(List::stream).toList(),
+ ErpPurchaseInvoiceOrderDO::getPurchaseOrderId);
+ List<ErpPurchaseInvoiceOrderDO> orderAllocations = invoiceService.getPurchaseInvoiceOrderListByPurchaseOrderIds(orderIds);
+ // 1.2.3 鑾峰彇閲囪喘璁㈠崟鍒楄〃锛堝惈涓昏鍗曪紝鍏煎鍘嗗彶鏁版嵁锛�
+ Set<Long> orderIdsAll = new HashSet<>(orderIds);
+ invoiceList.stream().map(ErpPurchaseInvoiceDO::getPurchaseOrderId)
+ .filter(java.util.Objects::nonNull).forEach(orderIdsAll::add);
Map<Long, ErpPurchaseOrderDO> orderMap = convertMap(
- purchaseOrderService.getPurchaseOrderList(convertList(invoiceList, ErpPurchaseInvoiceDO::getPurchaseOrderId)),
- ErpPurchaseOrderDO::getId);
+ purchaseOrderService.getPurchaseOrderList(new ArrayList<>(orderIdsAll)), ErpPurchaseOrderDO::getId);
+ // 1.2.4 鑾峰彇鍒嗘憡璁㈠崟鐨勪緵搴斿晢鍒楄〃锛堜竴寮犳潵绁ㄥ彲鑳芥秹鍙婂涓緵搴斿晢锛�
+ Map<Long, SrmSupplierRespDTO> orderSupplierMap = srmSupplierApi.getSupplierList(
+ convertSet(orderMap.values(), ErpPurchaseOrderDO::getSupplierId)).getCheckedData().stream()
+ .collect(java.util.stream.Collectors.toMap(SrmSupplierRespDTO::getId, v -> v, (a, b) -> a));
// 1.3 鑾峰彇鍒涘缓浜哄垪琛�
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSet(invoiceList, invoice -> NumberUtils.parseLong(invoice.getCreator())));
@@ -153,9 +181,37 @@
return BeanUtils.toBean(invoiceList, ErpPurchaseInvoiceRespVO.class, (invoiceVO) -> {
// 2.1 鎷兼帴渚涘簲鍟嗗悕绉�
findAndThen(supplierMap, invoiceVO.getSupplierId(), supplier -> invoiceVO.setSupplierName(supplier.getName()));
- // 2.2 鎷兼帴閲囪喘璁㈠崟淇℃伅
+ // 2.2 鎷兼帴閲囪喘璁㈠崟淇℃伅锛堜富璁㈠崟锛�
findAndThen(orderMap, invoiceVO.getPurchaseOrderId(), order ->
invoiceVO.setOrder(BeanUtils.toBean(order, ErpPurchaseOrderRespVO.class)));
+ // 2.2.1 鎷兼帴閲囪喘璁㈠崟鍒嗘憡鏄庣粏
+ List<ErpPurchaseInvoiceOrderDO> rows = allocationMap.getOrDefault(invoiceVO.getId(), Collections.emptyList());
+ List<ErpPurchaseInvoiceOrderRespVO> allocationVOs = new ArrayList<>(rows.size());
+ for (ErpPurchaseInvoiceOrderDO row : rows) {
+ ErpPurchaseInvoiceOrderRespVO allocationVO = new ErpPurchaseInvoiceOrderRespVO()
+ .setPurchaseOrderId(row.getPurchaseOrderId()).setPrice(row.getPrice());
+ ErpPurchaseOrderDO order = orderMap.get(row.getPurchaseOrderId());
+ if (order != null) {
+ allocationVO.setOrderNo(order.getNo()).setSupplierId(order.getSupplierId())
+ .setOrderTotalPrice(order.getTotalPrice());
+ findAndThen(orderSupplierMap, order.getSupplierId(),
+ supplier -> allocationVO.setSupplierName(supplier.getName()));
+ }
+ // 璇ヨ鍗曞叾浠栨潵绁ㄥ凡鍗犵敤閲戦 = 鍏ㄩ儴鍒嗘憡 - 鏈紶鏉ョエ鐨勫垎鎽�
+ BigDecimal otherInvoicedPrice = orderAllocations.stream()
+ .filter(other -> ObjectUtil.equal(other.getPurchaseOrderId(), row.getPurchaseOrderId())
+ && !ObjectUtil.equal(other.getInvoiceId(), invoiceVO.getId()))
+ .map(ErpPurchaseInvoiceOrderDO::getPrice)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ allocationVO.setInvoicedPrice(otherInvoicedPrice);
+ if (order != null) {
+ allocationVO.setRemainPrice(order.getTotalPrice().subtract(otherInvoicedPrice));
+ }
+ allocationVOs.add(allocationVO);
+ }
+ invoiceVO.setOrderAllocations(allocationVOs);
+ invoiceVO.setOrderCount(allocationVOs.size());
+ invoiceVO.setOrderNos(CollUtil.join(allocationVOs, "銆�", ErpPurchaseInvoiceOrderRespVO::getOrderNo));
// 2.3 鎷兼帴鍒涘缓浜哄悕绉�
MapUtils.findAndThen(userMap, NumberUtils.parseLong(invoiceVO.getCreator()),
user -> invoiceVO.setCreatorName(user.getNickname()));
@@ -169,24 +225,8 @@
});
}
- @PutMapping("/update-status")
- @Operation(summary = "鏇存柊鏉ョエ鐨勭姸鎬侊紙瀹℃牳/鍙嶅鏍革級")
- @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:update-status')")
- public CommonResult<Boolean> updatePurchaseInvoiceStatus(@RequestParam("id") Long id,
- @RequestParam("status") Integer status) {
- invoiceService.updatePurchaseInvoiceStatus(id, status);
- return success(true);
- }
-
- @GetMapping("/audit-count")
- @Operation(summary = "鑾峰緱寰呭鏍告潵绁ㄦ暟閲�")
- @PreAuthorize("@ss.hasPermission('erp:purchase-invoice:query')")
- public CommonResult<Long> getAuditInvoiceCount() {
- return success(invoiceService.getAuditInvoiceCount());
- }
-
@GetMapping("/simple-list")
- @Operation(summary = "鑾峰緱鏉ョエ绮剧畝鍒楄〃", description = "鍙寘鍚鏍搁�氳繃涓斿凡涓婁紶鍙戠エ闄勪欢鐨勬潵绁紝涓昏鐢ㄤ簬浠樻鍒涘缓鏃堕�夋嫨鍏宠仈鏉ョエ")
+ @Operation(summary = "鑾峰緱鏉ョエ绮剧畝鍒楄〃", description = "鍙寘鍚凡涓婁紶鍙戠エ闄勪欢鐨勬潵绁紝涓昏鐢ㄤ簬浠樻鍒涘缓鏃堕�夋嫨鍏宠仈鏉ョエ")
@Parameter(name = "supplierId", description = "渚涘簲鍟嗙紪鍙�", required = true)
@Parameter(name = "purchaseOrderId", description = "閲囪喘璁㈠崟缂栧彿锛堝彲閫夛紝鐢ㄤ簬鎸夎鍗曡繃婊わ級")
@PreAuthorize("@ss.hasPermission('erp:purchase-invoice:query')")
@@ -195,11 +235,9 @@
@RequestParam(value = "purchaseOrderId", required = false) Long purchaseOrderId) {
List<ErpPurchaseInvoiceDO> invoices;
if (purchaseOrderId != null) {
- invoices = invoiceService.getPurchaseInvoiceListByOrderIdAndStatus(purchaseOrderId,
- List.of(ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus()));
+ invoices = invoiceService.getPurchaseInvoiceListByOrderId(purchaseOrderId);
} else {
- invoices = invoiceService.getPurchaseInvoiceListBySupplierIdAndStatus(supplierId,
- List.of(ErpPurchaseInvoiceAuditStatusEnum.APPROVE.getStatus()));
+ invoices = invoiceService.getPurchaseInvoiceListBySupplierId(supplierId);
}
if (CollUtil.isEmpty(invoices)) {
return success(Collections.emptyList());
@@ -225,7 +263,7 @@
.setId(invoice.getId()).setNo(invoice.getNo()).setInvoiceNo(invoice.getInvoiceNo())
.setInvoiceTitle(invoice.getInvoiceTitle()).setPrice(invoice.getPrice())
.setSupplierId(invoice.getSupplierId()).setPurchaseOrderId(invoice.getPurchaseOrderId())
- .setAuditStatus(invoice.getAuditStatus()).setHasAttachment(true)
+ .setHasAttachment(true)
.setRemainingInvoicePrice(remainingPrice));
}
return success(result);
--
Gitblit v1.9.3