From 620bb4712a31791231c4381581f0f60088f079fe Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 27 五月 2026 14:03:45 +0800
Subject: [PATCH] Merge branch 'refs/heads/dev_New_pro' into dev_宁夏_英泽防锈
---
src/main/java/com/ruoyi/ai/tools/SalesAgentTools.java | 426 ++++++++++++++++++++++++++++++++++++----------------
1 files changed, 292 insertions(+), 134 deletions(-)
diff --git a/src/main/java/com/ruoyi/ai/tools/SalesAgentTools.java b/src/main/java/com/ruoyi/ai/tools/SalesAgentTools.java
index b56144b..0f7e586 100644
--- a/src/main/java/com/ruoyi/ai/tools/SalesAgentTools.java
+++ b/src/main/java/com/ruoyi/ai/tools/SalesAgentTools.java
@@ -3,24 +3,22 @@
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
-import com.ruoyi.account.mapper.SalesReceiptReturnMapper;
-import com.ruoyi.account.pojo.SalesReceiptReturn;
+import com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper;
+import com.ruoyi.account.pojo.sales.AccountSalesCollection;
import com.ruoyi.ai.context.AiSessionUserContext;
import com.ruoyi.basic.dto.CustomerDto;
import com.ruoyi.basic.mapper.CustomerMapper;
import com.ruoyi.basic.vo.CustomerVo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.security.LoginUser;
-import com.ruoyi.sales.dto.InvoiceLedgerDto;
-import com.ruoyi.sales.mapper.InvoiceLedgerMapper;
-import com.ruoyi.sales.mapper.ReceiptPaymentMapper;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.mapper.ShippingInfoMapper;
-import com.ruoyi.sales.pojo.ReceiptPayment;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.pojo.ShippingInfo;
+import com.ruoyi.stock.mapper.StockOutRecordMapper;
+import com.ruoyi.stock.pojo.StockOutRecord;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
@@ -34,16 +32,7 @@
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -62,26 +51,23 @@
private final SalesLedgerMapper salesLedgerMapper;
private final SalesQuotationMapper salesQuotationMapper;
private final ShippingInfoMapper shippingInfoMapper;
- private final ReceiptPaymentMapper receiptPaymentMapper;
- private final InvoiceLedgerMapper invoiceLedgerMapper;
- private final SalesReceiptReturnMapper salesReceiptReturnMapper;
+ private final AccountSalesCollectionMapper accountSalesCollectionMapper;
+ private final StockOutRecordMapper stockOutRecordMapper;
private final AiSessionUserContext aiSessionUserContext;
public SalesAgentTools(CustomerMapper customerMapper,
SalesLedgerMapper salesLedgerMapper,
SalesQuotationMapper salesQuotationMapper,
ShippingInfoMapper shippingInfoMapper,
- ReceiptPaymentMapper receiptPaymentMapper,
- InvoiceLedgerMapper invoiceLedgerMapper,
- SalesReceiptReturnMapper salesReceiptReturnMapper,
+ AccountSalesCollectionMapper accountSalesCollectionMapper,
+ StockOutRecordMapper stockOutRecordMapper,
AiSessionUserContext aiSessionUserContext) {
this.customerMapper = customerMapper;
this.salesLedgerMapper = salesLedgerMapper;
this.salesQuotationMapper = salesQuotationMapper;
this.shippingInfoMapper = shippingInfoMapper;
- this.receiptPaymentMapper = receiptPaymentMapper;
- this.invoiceLedgerMapper = invoiceLedgerMapper;
- this.salesReceiptReturnMapper = salesReceiptReturnMapper;
+ this.accountSalesCollectionMapper = accountSalesCollectionMapper;
+ this.stockOutRecordMapper = stockOutRecordMapper;
this.aiSessionUserContext = aiSessionUserContext;
}
@@ -261,36 +247,35 @@
@P(value = "杩斿洖鏉℃暟锛岄粯璁�10锛屾渶澶�30", required = false) Integer limit) {
LoginUser loginUser = currentLoginUser(memoryId);
DateRange range = resolveDateRange(startDate, endDate, null);
- LambdaQueryWrapper<SalesReceiptReturn> wrapper = new LambdaQueryWrapper<>();
- applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), SalesReceiptReturn::getDeptId);
+ LambdaQueryWrapper<AccountSalesCollection> wrapper = new LambdaQueryWrapper<>();
+ applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), AccountSalesCollection::getDeptId);
if (StringUtils.hasText(keyword)) {
- wrapper.and(w -> w.like(SalesReceiptReturn::getRefundId, keyword)
- .or().like(SalesReceiptReturn::getTransactionNo, keyword)
- .or().like(SalesReceiptReturn::getPaymentAccountName, keyword));
+ wrapper.and(w -> w.like(AccountSalesCollection::getCollectionNumber, keyword)
+ .or().like(AccountSalesCollection::getCollectionMethod, keyword)
+ .or().like(AccountSalesCollection::getRemark, keyword));
}
- wrapper.ge(SalesReceiptReturn::getCreateTime, range.start().atStartOfDay())
- .le(SalesReceiptReturn::getCreateTime, range.end().atTime(23, 59, 59))
- .orderByDesc(SalesReceiptReturn::getCreateTime, SalesReceiptReturn::getId)
+ wrapper.ge(AccountSalesCollection::getCollectionDate, range.start())
+ .le(AccountSalesCollection::getCollectionDate, range.end())
+ .orderByDesc(AccountSalesCollection::getCollectionDate, AccountSalesCollection::getId)
.last("limit " + normalizeLimit(limit));
- List<SalesReceiptReturn> rows = defaultList(salesReceiptReturnMapper.selectList(wrapper));
+ List<AccountSalesCollection> rows = defaultList(accountSalesCollectionMapper.selectList(wrapper));
BigDecimal returnAmount = rows.stream()
- .map(SalesReceiptReturn::getActualAmount)
+ .map(AccountSalesCollection::getCollectionAmount)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
List<Map<String, Object>> items = rows.stream().map(item -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", item.getId());
- map.put("refundId", safe(item.getRefundId()));
- map.put("paymentAccount", safe(item.getPaymentAccount()));
- map.put("paymentAccountName", safe(item.getPaymentAccountName()));
- map.put("paymentMethod", item.getPaymentMethod());
- map.put("actualAmount", item.getActualAmount());
- map.put("fee", item.getFee());
- map.put("discountAmount", item.getDiscountAmount());
- map.put("transactionNo", safe(item.getTransactionNo()));
- map.put("createTime", formatDateTime(item.getCreateTime()));
+ map.put("refundId", safe(item.getCollectionNumber()));
+ map.put("collectionNumber", safe(item.getCollectionNumber()));
+ map.put("paymentMethod", safe(item.getCollectionMethod()));
+ map.put("actualAmount", item.getCollectionAmount());
+ map.put("collectionAmount", item.getCollectionAmount());
+ map.put("customerId", item.getCustomerId());
+ map.put("remark", safe(item.getRemark()));
+ map.put("createTime", formatDate(item.getCollectionDate()));
return map;
}).collect(Collectors.toList());
@@ -307,55 +292,59 @@
@P(value = "杩斿洖鏉℃暟锛岄粯璁�10锛屾渶澶�30", required = false) Integer limit) {
LoginUser loginUser = currentLoginUser(memoryId);
DateRange range = resolveDateRange(startDate, endDate, null);
- LambdaQueryWrapper<ReceiptPayment> wrapper = new LambdaQueryWrapper<>();
- applyTenantFilter(wrapper, loginUser.getTenantId(), ReceiptPayment::getTenantId);
- applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), ReceiptPayment::getDeptId);
- wrapper.ge(ReceiptPayment::getReceiptPaymentDate, range.start())
- .le(ReceiptPayment::getReceiptPaymentDate, range.end())
- .orderByDesc(ReceiptPayment::getReceiptPaymentDate, ReceiptPayment::getId);
- List<ReceiptPayment> payments = defaultList(receiptPaymentMapper.selectList(wrapper));
- if (payments.isEmpty()) {
- return jsonResponse(true, "sales_customer_interaction_list", "鏈煡璇㈠埌瀹㈡埛寰�鏉ヨ褰�", rangeSummary(range, 0, keyword), Map.of("items", List.of()), Map.of());
+ List<AccountSalesCollection> collections = queryCollections(loginUser, range);
+ if (collections.isEmpty()) {
+ return jsonResponse(true, "sales_customer_interaction_list", "no_customer_interactions", rangeSummary(range, 0, keyword), Map.of("items", List.of()), Map.of());
}
- List<Long> ledgerIds = payments.stream()
- .map(ReceiptPayment::getSalesLedgerId)
- .filter(Objects::nonNull)
- .distinct()
- .collect(Collectors.toList());
+ Map<Integer, Set<Long>> ledgerIdsByCollectionId = mapCollectionLedgerIds(loginUser, collections);
+ Set<Long> ledgerIds = ledgerIdsByCollectionId.values().stream()
+ .flatMap(Collection::stream)
+ .collect(Collectors.toSet());
Map<Long, SalesLedger> ledgerMap = defaultList(salesLedgerMapper.selectBatchIds(ledgerIds)).stream()
.filter(ledger -> tenantMatched(ledger.getTenantId(), loginUser.getTenantId()))
.collect(Collectors.toMap(SalesLedger::getId, item -> item, (a, b) -> a, LinkedHashMap::new));
- List<ReceiptPayment> filtered = payments.stream()
- .filter(item -> matchInteractionKeyword(item, ledgerMap.get(item.getSalesLedgerId()), keyword))
- .limit(normalizeLimit(limit))
- .collect(Collectors.toList());
+ int finalLimit = normalizeLimit(limit);
+ List<Map<String, Object>> items = new ArrayList<>();
+ for (AccountSalesCollection collection : collections) {
+ Set<Long> relatedLedgerIds = ledgerIdsByCollectionId.get(collection.getId());
+ if (relatedLedgerIds == null || relatedLedgerIds.isEmpty()) {
+ if (!matchInteractionKeyword(collection, null, keyword)) {
+ continue;
+ }
+ items.add(toInteractionItem(collection, null));
+ if (items.size() >= finalLimit) {
+ break;
+ }
+ continue;
+ }
+ for (Long ledgerId : relatedLedgerIds) {
+ SalesLedger ledger = ledgerMap.get(ledgerId);
+ if (ledger == null || !matchInteractionKeyword(collection, ledger, keyword)) {
+ continue;
+ }
+ items.add(toInteractionItem(collection, ledger));
+ if (items.size() >= finalLimit) {
+ break;
+ }
+ }
+ if (items.size() >= finalLimit) {
+ break;
+ }
+ }
- BigDecimal totalReceiptAmount = filtered.stream()
- .map(ReceiptPayment::getReceiptPaymentAmount)
- .filter(Objects::nonNull)
+ BigDecimal totalReceiptAmount = items.stream()
+ .map(item -> asBigDecimal(item.get("receiptPaymentAmount")))
.reduce(BigDecimal.ZERO, BigDecimal::add);
-
- List<Map<String, Object>> items = filtered.stream().map(item -> {
- SalesLedger ledger = ledgerMap.get(item.getSalesLedgerId());
- Map<String, Object> map = new LinkedHashMap<>();
- map.put("id", item.getId());
- map.put("salesLedgerId", item.getSalesLedgerId());
- map.put("salesContractNo", ledger == null ? "" : safe(ledger.getSalesContractNo()));
- map.put("customerName", ledger == null ? "" : safe(ledger.getCustomerName()));
- map.put("projectName", ledger == null ? "" : safe(ledger.getProjectName()));
- map.put("receiptPaymentDate", formatDate(item.getReceiptPaymentDate()));
- map.put("receiptPaymentAmount", item.getReceiptPaymentAmount());
- map.put("receiptPaymentType", safe(item.getReceiptPaymentType()));
- map.put("registrant", safe(item.getRegistrant()));
- return map;
- }).collect(Collectors.toList());
-
Map<String, Object> summary = rangeSummary(range, items.size(), keyword);
summary.put("totalReceiptAmount", totalReceiptAmount);
- summary.put("customerCount", items.stream().map(item -> String.valueOf(item.get("customerName"))).filter(StringUtils::hasText).distinct().count());
- return jsonResponse(true, "sales_customer_interaction_list", "宸茶繑鍥炲鎴峰線鏉ユ槑缁�", summary, Map.of("items", items), Map.of());
+ summary.put("customerCount", items.stream()
+ .map(item -> String.valueOf(item.get("customerName")))
+ .filter(StringUtils::hasText)
+ .distinct()
+ .count());
+ return jsonResponse(true, "sales_customer_interaction_list", "ok", summary, Map.of("items", items), Map.of());
}
@Tool(name = "鏌ヨ鍙戣揣鍙拌处", value = "鎸夊叧閿瘝鍜屾椂闂磋寖鍥存煡璇㈠彂璐у彴璐�")
@@ -426,7 +415,7 @@
List<SalesLedger> ledgers = querySalesLedgers(loginUser, range);
List<SalesQuotation> quotations = querySalesQuotations(loginUser, range);
List<ShippingInfo> shippings = queryShippings(loginUser, range);
- List<ReceiptPayment> receipts = queryReceipts(loginUser, range);
+
BigDecimal contractAmountTotal = ledgers.stream()
.map(SalesLedger::getContractAmount)
@@ -436,11 +425,6 @@
.map(SalesQuotation::getTotalAmount)
.filter(Objects::nonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
- BigDecimal receivedAmountTotal = receipts.stream()
- .map(ReceiptPayment::getReceiptPaymentAmount)
- .filter(Objects::nonNull)
- .reduce(BigDecimal.ZERO, BigDecimal::add);
- BigDecimal pendingAmountTotal = maxZero(contractAmountTotal.subtract(receivedAmountTotal));
long shippingCount = shippings.size();
long shippedCount = shippings.stream().filter(item -> isShippedStatus(item.getStatus())).count();
@@ -460,11 +444,12 @@
summary.put("shipRate", shipRate);
summary.put("contractAmountTotal", contractAmountTotal);
summary.put("quotationAmountTotal", quotationAmountTotal);
- summary.put("receivedAmountTotal", receivedAmountTotal);
- summary.put("pendingAmountTotal", pendingAmountTotal);
+ summary.put("receivedAmountTotal", BigDecimal.ZERO);
+ summary.put("pendingAmountTotal", BigDecimal.ZERO);
Map<String, Object> charts = new LinkedHashMap<>();
- charts.put("amountBarOption", buildAmountBarOption(contractAmountTotal, quotationAmountTotal, receivedAmountTotal, pendingAmountTotal));
+// charts.put("amountBarOption", buildAmountBarOption(contractAmountTotal, quotationAmountTotal, receivedAmountTotal, pendingAmountTotal));
+ charts.put("amountBarOption", buildAmountBarOption(contractAmountTotal, quotationAmountTotal, BigDecimal.ONE, BigDecimal.ONE));
charts.put("shippingPieOption", buildShippingPieOption(shippedCount, Math.max(shippingCount - shippedCount, 0)));
charts.put("customerTopBarOption", buildCustomerTopBarOption(topCustomers));
charts.put("contractTrendLineOption", buildContractTrendLineOption(trendData.labels(), trendData.values()));
@@ -858,28 +843,6 @@
return defaultList(shippingInfoMapper.selectList(wrapper));
}
- private List<ReceiptPayment> queryReceipts(LoginUser loginUser, DateRange range) {
- LambdaQueryWrapper<ReceiptPayment> wrapper = new LambdaQueryWrapper<>();
- applyTenantFilter(wrapper, loginUser.getTenantId(), ReceiptPayment::getTenantId);
- applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), ReceiptPayment::getDeptId);
- if (range != null) {
- wrapper.ge(ReceiptPayment::getReceiptPaymentDate, range.start())
- .le(ReceiptPayment::getReceiptPaymentDate, range.end());
- }
- return defaultList(receiptPaymentMapper.selectList(wrapper));
- }
-
- private List<ReceiptPayment> queryReceiptsByLedgerIds(LoginUser loginUser, List<Long> ledgerIds) {
- if (ledgerIds == null || ledgerIds.isEmpty()) {
- return List.of();
- }
- LambdaQueryWrapper<ReceiptPayment> wrapper = new LambdaQueryWrapper<>();
- applyTenantFilter(wrapper, loginUser.getTenantId(), ReceiptPayment::getTenantId);
- applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), ReceiptPayment::getDeptId);
- wrapper.in(ReceiptPayment::getSalesLedgerId, ledgerIds);
- return defaultList(receiptPaymentMapper.selectList(wrapper));
- }
-
private List<ShippingInfo> queryShippingsByLedgerIds(LoginUser loginUser, List<Long> ledgerIds) {
if (ledgerIds == null || ledgerIds.isEmpty()) {
return List.of();
@@ -896,24 +859,213 @@
return Map.of();
}
Map<Long, BigDecimal> result = new HashMap<>();
- for (InvoiceLedgerDto item : defaultList(invoiceLedgerMapper.invoicedTotal(ledgerIds))) {
- if (item.getSalesLedgerId() == null) {
- continue;
- }
- result.merge(item.getSalesLedgerId().longValue(), defaultDecimal(item.getInvoiceTotal()), BigDecimal::add);
- }
return result;
}
private Map<Long, BigDecimal> sumReceiptAmounts(LoginUser loginUser, List<Long> ledgerIds) {
+ if (ledgerIds == null || ledgerIds.isEmpty()) {
+ return Map.of();
+ }
+ List<SalesLedger> ledgers = defaultList(salesLedgerMapper.selectBatchIds(ledgerIds)).stream()
+ .filter(ledger -> tenantMatched(ledger.getTenantId(), loginUser.getTenantId()))
+ .collect(Collectors.toList());
+ if (ledgers.isEmpty()) {
+ return Map.of();
+ }
+
+ Set<Integer> customerIds = ledgers.stream()
+ .map(SalesLedger::getCustomerId)
+ .filter(Objects::nonNull)
+ .map(Long::intValue)
+ .collect(Collectors.toSet());
+ if (customerIds.isEmpty()) {
+ return Map.of();
+ }
+
+ LambdaQueryWrapper<AccountSalesCollection> wrapper = new LambdaQueryWrapper<>();
+ applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), AccountSalesCollection::getDeptId);
+ wrapper.in(AccountSalesCollection::getCustomerId, customerIds);
+ List<AccountSalesCollection> collections = defaultList(accountSalesCollectionMapper.selectList(wrapper));
+ if (collections.isEmpty()) {
+ return Map.of();
+ }
+
+ Map<Integer, Set<Long>> ledgerIdsByCollectionId = mapCollectionLedgerIds(loginUser, collections);
+ Map<Long, List<Long>> ledgerIdsByCustomerId = ledgers.stream()
+ .filter(item -> item.getId() != null && item.getCustomerId() != null)
+ .collect(Collectors.groupingBy(item -> item.getCustomerId().longValue(),
+ Collectors.mapping(SalesLedger::getId, Collectors.toList())));
+ Set<Long> targetLedgerIdSet = new HashSet<>(ledgerIds);
+
Map<Long, BigDecimal> result = new HashMap<>();
- for (ReceiptPayment item : queryReceiptsByLedgerIds(loginUser, ledgerIds)) {
- if (item.getSalesLedgerId() == null) {
+ for (AccountSalesCollection collection : collections) {
+ BigDecimal amount = defaultDecimal(collection.getCollectionAmount());
+ if (amount.compareTo(BigDecimal.ZERO) == 0) {
continue;
}
- result.merge(item.getSalesLedgerId(), defaultDecimal(item.getReceiptPaymentAmount()), BigDecimal::add);
+ Set<Long> relatedLedgerIds = ledgerIdsByCollectionId.getOrDefault(collection.getId(), Set.of());
+ if (!relatedLedgerIds.isEmpty()) {
+ for (Long ledgerId : relatedLedgerIds) {
+ if (targetLedgerIdSet.contains(ledgerId)) {
+ result.merge(ledgerId, amount, BigDecimal::add);
+ }
+ }
+ continue;
+ }
+ if (collection.getCustomerId() == null) {
+ continue;
+ }
+ List<Long> customerLedgerIds = ledgerIdsByCustomerId.get(collection.getCustomerId().longValue());
+ if (customerLedgerIds == null || customerLedgerIds.isEmpty()) {
+ continue;
+ }
+ for (Long ledgerId : customerLedgerIds) {
+ if (targetLedgerIdSet.contains(ledgerId)) {
+ result.merge(ledgerId, amount, BigDecimal::add);
+ }
+ }
}
return result;
+ }
+
+ private List<AccountSalesCollection> queryCollections(LoginUser loginUser, DateRange range) {
+ LambdaQueryWrapper<AccountSalesCollection> wrapper = new LambdaQueryWrapper<>();
+ applyDeptFilter(wrapper, loginUser.getCurrentDeptId(), AccountSalesCollection::getDeptId);
+ if (range != null) {
+ wrapper.ge(AccountSalesCollection::getCollectionDate, range.start())
+ .le(AccountSalesCollection::getCollectionDate, range.end());
+ }
+ wrapper.orderByDesc(AccountSalesCollection::getCollectionDate, AccountSalesCollection::getId);
+ return defaultList(accountSalesCollectionMapper.selectList(wrapper));
+ }
+
+ private Map<Integer, Set<Long>> mapCollectionLedgerIds(LoginUser loginUser, List<AccountSalesCollection> collections) {
+ Map<Integer, Set<Long>> result = new HashMap<>();
+ if (collections == null || collections.isEmpty()) {
+ return result;
+ }
+
+ Map<Integer, List<Long>> stockOutRecordIdsByCollection = new HashMap<>();
+ Set<Long> allStockOutRecordIds = new HashSet<>();
+ for (AccountSalesCollection collection : collections) {
+ if (collection.getId() == null) {
+ continue;
+ }
+ List<Long> stockOutRecordIds = parseLongIds(collection.getStockOutRecordIds());
+ if (stockOutRecordIds.isEmpty()) {
+ continue;
+ }
+ stockOutRecordIdsByCollection.put(collection.getId(), stockOutRecordIds);
+ allStockOutRecordIds.addAll(stockOutRecordIds);
+ }
+ if (allStockOutRecordIds.isEmpty()) {
+ return result;
+ }
+
+ List<StockOutRecord> stockOutRecords = defaultList(stockOutRecordMapper.selectList(new LambdaQueryWrapper<StockOutRecord>()
+ .in(StockOutRecord::getId, allStockOutRecordIds)));
+ if (stockOutRecords.isEmpty()) {
+ return result;
+ }
+ Map<Long, StockOutRecord> stockOutRecordMap = stockOutRecords.stream()
+ .filter(item -> item.getId() != null)
+ .collect(Collectors.toMap(StockOutRecord::getId, item -> item, (a, b) -> a));
+
+ Set<Long> shippingIds = stockOutRecords.stream()
+ .filter(this::isSalesOutboundRecord)
+ .map(StockOutRecord::getRecordId)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toSet());
+ if (shippingIds.isEmpty()) {
+ return result;
+ }
+
+ LambdaQueryWrapper<ShippingInfo> shippingWrapper = new LambdaQueryWrapper<>();
+ applyTenantFilter(shippingWrapper, loginUser.getTenantId(), ShippingInfo::getTenantId);
+ applyDeptFilter(shippingWrapper, loginUser.getCurrentDeptId(), ShippingInfo::getDeptId);
+ shippingWrapper.in(ShippingInfo::getId, shippingIds);
+ Map<Long, Long> ledgerIdByShippingId = defaultList(shippingInfoMapper.selectList(shippingWrapper)).stream()
+ .filter(item -> item.getId() != null && item.getSalesLedgerId() != null)
+ .collect(Collectors.toMap(ShippingInfo::getId, ShippingInfo::getSalesLedgerId, (a, b) -> a));
+
+ for (Map.Entry<Integer, List<Long>> entry : stockOutRecordIdsByCollection.entrySet()) {
+ Set<Long> ledgerIds = new LinkedHashSet<>();
+ for (Long stockOutRecordId : entry.getValue()) {
+ StockOutRecord stockOutRecord = stockOutRecordMap.get(stockOutRecordId);
+ if (!isSalesOutboundRecord(stockOutRecord)) {
+ continue;
+ }
+ Long ledgerId = ledgerIdByShippingId.get(stockOutRecord.getRecordId());
+ if (ledgerId != null) {
+ ledgerIds.add(ledgerId);
+ }
+ }
+ if (!ledgerIds.isEmpty()) {
+ result.put(entry.getKey(), ledgerIds);
+ }
+ }
+ return result;
+ }
+
+ private boolean isSalesOutboundRecord(StockOutRecord stockOutRecord) {
+ if (stockOutRecord == null || !StringUtils.hasText(stockOutRecord.getRecordType())) {
+ return false;
+ }
+ if (stockOutRecord.getApprovalStatus() != null && stockOutRecord.getApprovalStatus() != 1) {
+ return false;
+ }
+ return "13".equals(stockOutRecord.getRecordType().trim());
+ }
+
+ private List<Long> parseLongIds(String raw) {
+ if (!StringUtils.hasText(raw)) {
+ return List.of();
+ }
+ List<Long> result = new ArrayList<>();
+ for (String part : raw.split(",")) {
+ if (!StringUtils.hasText(part)) {
+ continue;
+ }
+ try {
+ result.add(Long.parseLong(part.trim()));
+ } catch (Exception ignored) {
+ }
+ }
+ return result;
+ }
+
+ private boolean matchInteractionKeyword(AccountSalesCollection collection, SalesLedger ledger, String keyword) {
+ if (!StringUtils.hasText(keyword)) {
+ return true;
+ }
+ String text = keyword.trim();
+ if (safe(collection.getCollectionNumber()).contains(text)
+ || safe(collection.getCollectionMethod()).contains(text)
+ || safe(collection.getRemark()).contains(text)) {
+ return true;
+ }
+ if (ledger == null) {
+ return false;
+ }
+ return safe(ledger.getSalesContractNo()).contains(text)
+ || safe(ledger.getCustomerName()).contains(text)
+ || safe(ledger.getProjectName()).contains(text);
+ }
+
+ private Map<String, Object> toInteractionItem(AccountSalesCollection collection, SalesLedger ledger) {
+ Map<String, Object> map = new LinkedHashMap<>();
+ map.put("id", collection.getId());
+ map.put("salesLedgerId", ledger == null ? null : ledger.getId());
+ map.put("salesContractNo", ledger == null ? "" : safe(ledger.getSalesContractNo()));
+ map.put("customerName", ledger == null ? "" : safe(ledger.getCustomerName()));
+ map.put("projectName", ledger == null ? "" : safe(ledger.getProjectName()));
+ map.put("receiptPaymentDate", formatDate(collection.getCollectionDate()));
+ map.put("receiptPaymentAmount", collection.getCollectionAmount());
+ map.put("receiptPaymentType", safe(collection.getCollectionMethod()));
+ map.put("collectionNumber", safe(collection.getCollectionNumber()));
+ map.put("registrant", collection.getCreateUser());
+ map.put("remark", safe(collection.getRemark()));
+ return map;
}
private boolean isLedgerFullyShipped(Long ledgerId, Map<Long, List<ShippingInfo>> shippingByLedgerId) {
@@ -952,17 +1104,6 @@
|| safe(customer.getContactPhone()).contains(text)
|| safe(customer.getCompanyPhone()).contains(text)
|| safe(customer.getUsageUserName()).contains(text);
- }
-
- private boolean matchInteractionKeyword(ReceiptPayment payment, SalesLedger ledger, String keyword) {
- if (!StringUtils.hasText(keyword)) {
- return true;
- }
- String text = keyword.trim();
- return safe(payment.getRegistrant()).contains(text)
- || (ledger != null && (safe(ledger.getCustomerName()).contains(text)
- || safe(ledger.getSalesContractNo()).contains(text)
- || safe(ledger.getProjectName()).contains(text)));
}
private boolean matchLedgerCustomerKeyword(SalesLedger ledger, String keyword) {
@@ -1150,6 +1291,23 @@
return value == null ? BigDecimal.ZERO : value;
}
+ private BigDecimal asBigDecimal(Object value) {
+ if (value == null) {
+ return BigDecimal.ZERO;
+ }
+ if (value instanceof BigDecimal decimal) {
+ return decimal;
+ }
+ if (value instanceof Number number) {
+ return new BigDecimal(String.valueOf(number));
+ }
+ try {
+ return new BigDecimal(String.valueOf(value));
+ } catch (Exception ignored) {
+ return BigDecimal.ZERO;
+ }
+ }
+
private BigDecimal maxZero(BigDecimal value) {
return value == null || value.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : value;
}
--
Gitblit v1.9.3