demand: TMS系统 - 运输管理 - 漏组批次统计 - 查询漏组批次统计列表、导出漏组详细数据、导出漏组批次统计查询接口数据支持同时选择多个月份查询/导出 TMS系统 - 客户账单管理 - 发票收款针对相同账单不同发票合并收款特殊逻辑特殊处理

committer: heyu
This commit is contained in:
aike 2025-09-28 16:12:44 +08:00
parent c6c73b0aba
commit 7fd45c391a
5 changed files with 95 additions and 51 deletions

View File

@ -1,10 +1,10 @@
/** /**
* @Project: emis * @Project: emis
* @Title: EmisSettlePayRel.java * @Title: EmisSettlePayRel.java
* @author linfso * @author linfso
* @date 2024-07-21 13:31:24 * @date 2024-07-21 13:31:24
* @Copyright: ShangHai Duta 2022 All rights reserved. * @Copyright: ShangHai Duta 2022 All rights reserved.
* @version v1.0 * @version v1.0
* @Description: <p> 支付子账单关联表 实体类 </p> * @Description: <p> 支付子账单关联表 实体类 </p>
*/ */
@ -44,6 +44,8 @@ public class EmisSettlePayRel extends BaseEntity
private String billNo; private String billNo;
/* 金额 */ /* 金额 */
private BigDecimal payMoney; private BigDecimal payMoney;
/* 发票申请序号 */
private String applySeqNo;
// 扩展参数 // 扩展参数
private EmisWaybill waybillDetail; private EmisWaybill waybillDetail;

View File

@ -5,6 +5,7 @@ import com.xdadan.erp.common.core.domain.BaseEntity;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
import java.util.List;
/** /**
* 漏组批次统计查询结果DTO * 漏组批次统计查询结果DTO
@ -27,4 +28,10 @@ public class EmisTmsSiteBatchMissStatistics extends BaseEntity {
/** 票数 */ /** 票数 */
private Integer ticketCount; private Integer ticketCount;
/** 多个寄件月份,逗号分隔,例如:2025-06,2025-07 */
private String billMonths;
/** 解析后的月份列表(yyyy-MM) */
private List<String> billMonthList;
} }

View File

@ -815,8 +815,8 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I
BigDecimal previousRecedMoney = invoiceRecord.getRecedMoney() != null ? invoiceRecord.getRecedMoney() BigDecimal previousRecedMoney = invoiceRecord.getRecedMoney() != null ? invoiceRecord.getRecedMoney()
: BigDecimal.ZERO; : BigDecimal.ZERO;
// 计算当前收款记录中与该发票相关的运单收款金额 // 计算当前收款记录中与该发票相关的运单收款金额(以applySeqNo关联)
BigDecimal currentInvoicePayMoney = calculateCurrentInvoicePayment(invoiceRecord, payRelList); BigDecimal currentInvoicePayMoney = calculateCurrentInvoicePayment(applySeqNo, payRelList);
// 计算新的总收款金额 = 之前的收款金额 + 当前收款金额 // 计算新的总收款金额 = 之前的收款金额 + 当前收款金额
BigDecimal totalRecedMoney = previousRecedMoney.add(currentInvoicePayMoney); BigDecimal totalRecedMoney = previousRecedMoney.add(currentInvoicePayMoney);
@ -847,58 +847,27 @@ public class EmisSettlePayRecordServiceImpl extends EmisBaseService implements I
} }
/** /**
* 计算当前收款记录中与该发票相关的运单收款金额 * 计算当前收款记录中与该发票相关的运单收款金额(按applySeqNo关联)
* *
* @param invoiceRecord 发票记录 * @param applySeqNo 发票申请序号
* @param payRelList 当前收款记录中的运单收款列表 * @param payRelList 当前收款记录中的运单收款列表
* @return 当前收款金额 * @return 当前收款金额
*/ */
private BigDecimal calculateCurrentInvoicePayment(EmisSettleInvoiceRecord invoiceRecord, private BigDecimal calculateCurrentInvoicePayment(String applySeqNo, List<EmisSettlePayRel> payRelList) {
List<EmisSettlePayRel> payRelList) {
try { try {
String settleBillNo = invoiceRecord.getSettleBillNo(); if (StringUtils.isEmpty(applySeqNo) || CollectionUtils.isEmpty(payRelList)) {
if (StringUtils.isEmpty(settleBillNo)) {
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
// 处理多个账单号的情况(用逗号分隔)
String[] settleBillNos = settleBillNo.split(",");
Set<String> allBillCodes = new HashSet<>();
for (String billNo : settleBillNos) {
String trimmedBillNo = billNo.trim();
if (StringUtils.isNotEmpty(trimmedBillNo)) {
// 通过账单号找到该账单下的所有运单
List<EmisSettleSubBill> subBillList = emisSettleSubBillMapper
.selectSubBillListBySettleBillNo(trimmedBillNo);
if (CollectionUtils.isNotEmpty(subBillList)) {
// 收集该账单下的所有运单号
Set<String> billCodes = subBillList.stream()
.map(EmisSettleSubBill::getBillCode)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
allBillCodes.addAll(billCodes);
}
}
}
if (allBillCodes.isEmpty()) {
return BigDecimal.ZERO;
}
// 计算当前收款记录中属于该发票相关运单的收款金额
BigDecimal currentPayment = BigDecimal.ZERO; BigDecimal currentPayment = BigDecimal.ZERO;
for (EmisSettlePayRel payRel : payRelList) { for (EmisSettlePayRel payRel : payRelList) {
if (payRel.getBillNo() != null && allBillCodes.contains(payRel.getBillNo()) if (applySeqNo.equals(payRel.getApplySeqNo()) && payRel.getPayMoney() != null) {
&& payRel.getPayMoney() != null) {
currentPayment = currentPayment.add(payRel.getPayMoney()); currentPayment = currentPayment.add(payRel.getPayMoney());
} }
} }
return currentPayment; return currentPayment;
} catch (Exception e) { } catch (Exception e) {
log.error("计算当前发票收款金额失败,申请序号: {}", invoiceRecord.getApplySeqNo(), e); log.error("计算当前发票收款金额失败,申请序号: {}", applySeqNo, e);
return BigDecimal.ZERO; return BigDecimal.ZERO;
} }
} }

View File

@ -46,6 +46,7 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
@Override @Override
public List<EmisTmsSiteBatchMissStatistics> selectStatisticsList( public List<EmisTmsSiteBatchMissStatistics> selectStatisticsList(
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
normalizeBillMonths(emisTmsSiteBatchMissStatistics);
log.info("查询漏组批次统计列表,startSiteCode: {}, billMonth: {}", log.info("查询漏组批次统计列表,startSiteCode: {}, billMonth: {}",
emisTmsSiteBatchMissStatistics.getStartSiteCode(), emisTmsSiteBatchMissStatistics.getBillMonth()); emisTmsSiteBatchMissStatistics.getStartSiteCode(), emisTmsSiteBatchMissStatistics.getBillMonth());
@ -61,6 +62,7 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
@Override @Override
public void exportStatisticsData(HttpServletResponse response, public void exportStatisticsData(HttpServletResponse response,
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
normalizeBillMonths(emisTmsSiteBatchMissStatistics);
try { try {
// 设置响应头 // 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
@ -240,6 +242,7 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
@Override @Override
public void exportDetailDataByMonthStream(HttpServletResponse response, public void exportDetailDataByMonthStream(HttpServletResponse response,
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) { EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
normalizeBillMonths(emisTmsSiteBatchMissStatistics);
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
try { try {
// 设置响应头 // 设置响应头
@ -446,5 +449,36 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
} }
} }
/**
* 归一化 billMonths 到 billMonthList,支持逗号分隔的多月份(yyyy-MM)。
*/
private void normalizeBillMonths(EmisTmsSiteBatchMissStatistics query) {
if (query == null) {
return;
}
if (query.getBillMonthList() != null && !query.getBillMonthList().isEmpty()) {
return;
}
List<String> result = new ArrayList<>();
String months = query.getBillMonths();
if (months != null && months.trim().length() > 0) {
String[] parts = months.split(",");
for (String p : parts) {
if (p != null) {
String v = p.trim();
if (v.length() > 0) {
result.add(v);
}
}
}
}
if (result.isEmpty() && query.getBillMonth() != null) {
synchronized (MONTH_FORMAT) {
result.add(MONTH_FORMAT.format(query.getBillMonth()));
}
}
if (!result.isEmpty()) {
query.setBillMonthList(result);
}
}
} }

View File

@ -24,8 +24,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startSiteCode != null and startSiteCode != ''"> <if test="startSiteCode != null and startSiteCode != ''">
AND bm.start_site_code = #{startSiteCode} AND bm.start_site_code = #{startSiteCode}
</if> </if>
<if test="billMonth != null"> <if test="billMonthList != null and billMonthList.size() &gt; 0">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m') AND DATE_FORMAT(w.send_date, '%Y-%m') IN
<foreach collection="billMonthList" item="bm" open="(" separator="," close=")">
#{bm}
</foreach>
</if>
<if test="billMonthList == null or billMonthList.size() == 0">
<if test="billMonth != null">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m')
</if>
</if> </if>
GROUP BY bm.start_site_code, s.site_name, DATE_FORMAT(w.send_date, '%Y-%m') GROUP BY bm.start_site_code, s.site_name, DATE_FORMAT(w.send_date, '%Y-%m')
ORDER BY w.send_date,bm.start_site_code ORDER BY w.send_date,bm.start_site_code
@ -68,8 +76,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startSiteCode != null and startSiteCode != ''"> <if test="startSiteCode != null and startSiteCode != ''">
AND m.start_site_code = #{startSiteCode} AND m.start_site_code = #{startSiteCode}
</if> </if>
<if test="billMonth != null"> <if test="billMonthList != null and billMonthList.size() &gt; 0">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m') AND DATE_FORMAT(w.send_date, '%Y-%m') IN
<foreach collection="billMonthList" item="bm" open="(" separator="," close=")">
#{bm}
</foreach>
</if>
<if test="billMonthList == null or billMonthList.size() == 0">
<if test="billMonth != null">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m')
</if>
</if> </if>
ORDER BY w.send_date DESC, m.bill_code ORDER BY w.send_date DESC, m.bill_code
</select> </select>
@ -112,8 +128,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="query.startSiteCode != null and query.startSiteCode != ''"> <if test="query.startSiteCode != null and query.startSiteCode != ''">
AND m.start_site_code = #{query.startSiteCode} AND m.start_site_code = #{query.startSiteCode}
</if> </if>
<if test="query.billMonth != null"> <if test="query.billMonthList != null and query.billMonthList.size() &gt; 0">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{query.billMonth}, '%Y-%m') AND DATE_FORMAT(w.send_date, '%Y-%m') IN
<foreach collection="query.billMonthList" item="bm" open="(" separator="," close=")">
#{bm}
</foreach>
</if>
<if test="query.billMonthList == null or query.billMonthList.size() == 0">
<if test="query.billMonth != null">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{query.billMonth}, '%Y-%m')
</if>
</if> </if>
ORDER BY w.send_date DESC, m.bill_code ORDER BY w.send_date DESC, m.bill_code
LIMIT #{offset}, #{limit} LIMIT #{offset}, #{limit}
@ -128,8 +152,16 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startSiteCode != null and startSiteCode != ''"> <if test="startSiteCode != null and startSiteCode != ''">
AND m.start_site_code = #{startSiteCode} AND m.start_site_code = #{startSiteCode}
</if> </if>
<if test="billMonth != null"> <if test="billMonthList != null and billMonthList.size() &gt; 0">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m') AND DATE_FORMAT(w.send_date, '%Y-%m') IN
<foreach collection="billMonthList" item="bm" open="(" separator="," close=")">
#{bm}
</foreach>
</if>
<if test="billMonthList == null or billMonthList.size() == 0">
<if test="billMonth != null">
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m')
</if>
</if> </if>
</select> </select>