✨ 新增应收账单日期类型筛选
This commit is contained in:
@@ -24,6 +24,9 @@ public class ArBillGenerateQuery
|
||||
@JsonDeserialize(using = StrictDateDeserializer.class)
|
||||
private Date billPeriodEnd;
|
||||
|
||||
/** 截止日筛选字段:BIZ_DATE=计费时间,PICKUP_DATE=收货时间;历史请求默认计费时间。 */
|
||||
private String dateType = "BIZ_DATE";
|
||||
|
||||
private String currency;
|
||||
|
||||
/** 订单号、运单号或转单号;支持换行、逗号、分号或空格分隔多个号码。 */
|
||||
|
||||
@@ -26,6 +26,8 @@ public class ArBillGenerateRequest
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@JsonDeserialize(using = StrictDateDeserializer.class)
|
||||
private Date billPeriodEnd;
|
||||
/** 截止日筛选字段:BIZ_DATE=计费时间,PICKUP_DATE=收货时间;历史任务默认计费时间。 */
|
||||
private String dateType = "BIZ_DATE";
|
||||
/** 手动模式选中的来源订单 ID;全选模式为空。 */
|
||||
private List<String> sourceBillIds;
|
||||
/** 选择模式:EXPLICIT 手动选择,ALL_MATCHED 全选查询结果。 */
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.bms.ar.enums;
|
||||
|
||||
/** 应收账单生成时用于截止日筛选的来源订单日期字段。 */
|
||||
public enum ArBillDateType
|
||||
{
|
||||
/** 计费时间,对应 prc_order_bill.biz_date。 */
|
||||
BIZ_DATE("BIZ_DATE"),
|
||||
/** 收货时间,对应 prc_order_bill.pickup_date。 */
|
||||
PICKUP_DATE("PICKUP_DATE");
|
||||
|
||||
private final String code;
|
||||
|
||||
ArBillDateType(String code)
|
||||
{
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
/** 历史请求未携带日期类型时按计费时间处理。 */
|
||||
public static ArBillDateType of(String code)
|
||||
{
|
||||
if (code == null || code.trim().isEmpty())
|
||||
{
|
||||
return BIZ_DATE;
|
||||
}
|
||||
for (ArBillDateType type : values())
|
||||
{
|
||||
if (type.code.equalsIgnoreCase(code.trim()))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ import com.bms.ar.domain.ArExportTemplate;
|
||||
import com.bms.ar.event.ArBillExportTaskEvent;
|
||||
import com.bms.ar.event.ArBillGenerateTaskEvent;
|
||||
import com.bms.ar.enums.ArBillGenerateTaskStatus;
|
||||
import com.bms.ar.enums.ArBillDateType;
|
||||
import com.bms.ar.enums.ArBillGenerationStatus;
|
||||
import com.bms.ar.enums.ArBillSelectionMode;
|
||||
import com.bms.ar.enums.ArBillStatus;
|
||||
@@ -319,7 +320,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
List<String> excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo());
|
||||
List<PrcOrderBill> result = sourceBillMapper.selectPrcOrderBillByCustomerPeriod(query.getCustomerId(),
|
||||
query.getCustomerCode(), orderIdentifiers,
|
||||
excludeOrderIdentifiers, query.getBillPeriodEnd(), query.getCurrency(),
|
||||
excludeOrderIdentifiers, query.getBillPeriodEnd(), query.getDateType(), query.getCurrency(),
|
||||
eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(), null);
|
||||
log.debug("应收账单生成范围预览查询完成,customerId={}, billPeriodEnd={}, currency={}, resultCount={}, costMs={}",
|
||||
query.getCustomerId(), query.getBillPeriodEnd(), safeLogValue(query.getCurrency()),
|
||||
@@ -349,7 +350,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
List<String> excludeOrderIdentifiers = normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo());
|
||||
BigDecimal total = nvl(sourceBillMapper.sumPrcOrderBillIncomeByCustomerPeriod(query.getCustomerId(),
|
||||
query.getCustomerCode(), orderIdentifiers,
|
||||
excludeOrderIdentifiers, query.getBillPeriodEnd(), query.getCurrency(),
|
||||
excludeOrderIdentifiers, query.getBillPeriodEnd(), query.getDateType(), query.getCurrency(),
|
||||
eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode()));
|
||||
log.debug("应收账单生成范围金额汇总完成,customerId={}, billPeriodEnd={}, currency={}, costMs={}",
|
||||
query.getCustomerId(), query.getBillPeriodEnd(), safeLogValue(query.getCurrency()),
|
||||
@@ -604,7 +605,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
int totalCount = sourceBillMapper.countPrcOrderBillByCustomerPeriod(
|
||||
request.getCustomerId(), request.getCustomerCode(),
|
||||
normalizeOrderIdentifiers(request.getOrderOrTrackingNo()),
|
||||
request.getBillPeriodEnd(), request.getCurrency(), eligibleOrderBillStatuses(),
|
||||
request.getBillPeriodEnd(), request.getDateType(), request.getCurrency(), eligibleOrderBillStatuses(),
|
||||
ArIncomeBillFeeStatus.UNBILLED.getCode(), task.getSnapshotCreateTime(), null,
|
||||
excludedSourceBillIds, excludedOrderIdentifiers);
|
||||
if (totalCount <= 0) {
|
||||
@@ -731,7 +732,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
List<PrcOrderBill> sources = sourceBillMapper.selectPrcOrderBillByCustomerPeriodCursor(
|
||||
request.getCustomerId(), request.getCustomerCode(),
|
||||
normalizeOrderIdentifiers(request.getOrderOrTrackingNo()),
|
||||
request.getBillPeriodEnd(), StringUtils.isEmpty(request.getCurrency()) ? "CNY" : request.getCurrency(),
|
||||
request.getBillPeriodEnd(), request.getDateType(),
|
||||
StringUtils.isEmpty(request.getCurrency()) ? "CNY" : request.getCurrency(),
|
||||
eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(),
|
||||
task.getSnapshotCreateTime(), task.getLastSourceBillId(),
|
||||
explicitIds, selectionMode == ArBillSelectionMode.ALL_MATCHED ? excludedSourceBillIds : null,
|
||||
@@ -836,7 +838,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
}
|
||||
int processedCount = (task.getProcessedCount() == null ? 0 : task.getProcessedCount()) + sources.size();
|
||||
BigDecimal totalAmount = nvl(task.getTotalAmount()).add(batchAmount);
|
||||
Date periodStart = earliestBizDate(sources);
|
||||
Date periodStart = earliestDate(sources, request.getDateType());
|
||||
billMapper.updateArBillProgress(bill.getArBillId(), processedCount, totalAmount, totalAmount,
|
||||
periodStart, task.getCreateBy());
|
||||
String lastSourceBillId = sources.get(sources.size() - 1).getBillId();
|
||||
@@ -2181,6 +2183,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
if (StringUtils.isNotEmpty(request.getRemark()) && request.getRemark().trim().length() > 500) {
|
||||
throw new ServiceException("备注不能超过500个字符");
|
||||
}
|
||||
request.setDateType(normalizeDateType(request.getDateType()));
|
||||
// 生成任务会保存原始请求快照,先在入任务前校验号码数量,避免后台任务创建后才失败。
|
||||
normalizeOrderIdentifiers(request.getOrderOrTrackingNo());
|
||||
}
|
||||
@@ -2190,6 +2193,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
|| query.getBillPeriodEnd() == null) {
|
||||
throw new ServiceException("客户和账单截止日不能为空");
|
||||
}
|
||||
query.setDateType(normalizeDateType(query.getDateType()));
|
||||
int identifierCount = normalizeOrderIdentifiers(query.getOrderOrTrackingNo()).size()
|
||||
+ normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo()).size();
|
||||
if (identifierCount > ORDER_IDENTIFIER_LIMIT) {
|
||||
@@ -2203,16 +2207,26 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
return Arrays.asList(ArOrderBillStatus.UNBILLED.getCode(), ArOrderBillStatus.PARTIAL.getCode());
|
||||
}
|
||||
|
||||
private Date earliestBizDate(List<PrcOrderBill> sources) {
|
||||
private Date earliestDate(List<PrcOrderBill> sources, String dateType) {
|
||||
boolean usePickupDate = ArBillDateType.PICKUP_DATE.getCode().equals(dateType);
|
||||
Date earliest = null;
|
||||
for (PrcOrderBill source : sources) {
|
||||
if (source.getBizDate() != null && (earliest == null || source.getBizDate().before(earliest))) {
|
||||
earliest = source.getBizDate();
|
||||
Date sourceDate = usePickupDate ? source.getPickupDate() : source.getBizDate();
|
||||
if (sourceDate != null && (earliest == null || sourceDate.before(earliest))) {
|
||||
earliest = sourceDate;
|
||||
}
|
||||
}
|
||||
return earliest == null ? new Date() : earliest;
|
||||
}
|
||||
|
||||
private String normalizeDateType(String dateType) {
|
||||
ArBillDateType type = ArBillDateType.of(dateType);
|
||||
if (type == null) {
|
||||
throw new ServiceException("账单日期类型无效");
|
||||
}
|
||||
return type.getCode();
|
||||
}
|
||||
|
||||
private List<String> normalizeSourceBillIds(List<String> sourceBillIds) {
|
||||
LinkedHashSet<String> uniqueIds = new LinkedHashSet<>();
|
||||
if (sourceBillIds != null) {
|
||||
|
||||
@@ -63,7 +63,7 @@ public interface PrcOrderBillMapper
|
||||
public List<PrcOrderBill> selectPrcOrderBillByCustomerPeriod(@Param("customerId") Long customerId,
|
||||
@Param("customerCode") String customerCode, @Param("orderIdentifiers") List<String> orderIdentifiers,
|
||||
@Param("excludeOrderIdentifiers") List<String> excludeOrderIdentifiers,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("currency") String currency,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("dateType") String dateType, @Param("currency") String currency,
|
||||
@Param("arBillStatuses") List<String> arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus,
|
||||
@Param("excludedBillIds") List<String> excludedBillIds);
|
||||
|
||||
@@ -71,13 +71,13 @@ public interface PrcOrderBillMapper
|
||||
BigDecimal sumPrcOrderBillIncomeByCustomerPeriod(@Param("customerId") Long customerId,
|
||||
@Param("customerCode") String customerCode, @Param("orderIdentifiers") List<String> orderIdentifiers,
|
||||
@Param("excludeOrderIdentifiers") List<String> excludeOrderIdentifiers,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("currency") String currency,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("dateType") String dateType, @Param("currency") String currency,
|
||||
@Param("arBillStatuses") List<String> arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus);
|
||||
|
||||
/** 异步生成账单按 bill_id 游标读取一批来源订单。 */
|
||||
List<PrcOrderBill> selectPrcOrderBillByCustomerPeriodCursor(@Param("customerId") Long customerId,
|
||||
@Param("customerCode") String customerCode, @Param("orderIdentifiers") List<String> orderIdentifiers,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("currency") String currency,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("dateType") String dateType, @Param("currency") String currency,
|
||||
@Param("arBillStatuses") List<String> arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus,
|
||||
@Param("snapshotCreateTime") Date snapshotCreateTime,
|
||||
@Param("lastSourceBillId") String lastSourceBillId, @Param("billIds") List<String> billIds,
|
||||
@@ -86,7 +86,7 @@ public interface PrcOrderBillMapper
|
||||
|
||||
int countPrcOrderBillByCustomerPeriod(@Param("customerId") Long customerId,
|
||||
@Param("customerCode") String customerCode, @Param("orderIdentifiers") List<String> orderIdentifiers,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("currency") String currency,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("dateType") String dateType, @Param("currency") String currency,
|
||||
@Param("arBillStatuses") List<String> arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus,
|
||||
@Param("snapshotCreateTime") Date snapshotCreateTime,
|
||||
@Param("billIds") List<String> billIds, @Param("excludedBillIds") List<String> excludedBillIds,
|
||||
@@ -95,7 +95,7 @@ public interface PrcOrderBillMapper
|
||||
/** 按生成账单时用户勾选的订单读取,并再次校验账单筛选条件。 */
|
||||
public List<PrcOrderBill> selectPrcOrderBillByCustomerCutoffAndIds(@Param("customerId") Long customerId,
|
||||
@Param("customerCode") String customerCode, @Param("orderIdentifiers") List<String> orderIdentifiers,
|
||||
@Param("cutoffDate") Date cutoffDate,
|
||||
@Param("cutoffDate") Date cutoffDate, @Param("dateType") String dateType,
|
||||
@Param("currency") String currency, @Param("billIds") List<String> billIds,
|
||||
@Param("arBillStatuses") List<String> arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus);
|
||||
|
||||
|
||||
@@ -639,6 +639,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
)
|
||||
</sql>
|
||||
|
||||
<!-- 截止日按用户选择的日期类型筛选;字段名固定在 SQL 中,避免动态列名注入。 -->
|
||||
<sql id="arBillCutoffDateCondition">
|
||||
<choose>
|
||||
<when test="dateType != null and dateType == 'PICKUP_DATE'">
|
||||
and p.pickup_date < DATE_ADD(#{cutoffDate}, INTERVAL 1 DAY)
|
||||
</when>
|
||||
<otherwise>
|
||||
and p.biz_date < DATE_ADD(#{cutoffDate}, INTERVAL 1 DAY)
|
||||
</otherwise>
|
||||
</choose>
|
||||
</sql>
|
||||
|
||||
<select id="selectPrcOrderBillByCustomerPeriod" resultMap="PrcOrderBillArSourceResult">
|
||||
<include refid="selectArBillSourceVo"/>
|
||||
where p.customer_id = #{customerId}
|
||||
@@ -661,7 +673,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
and p.biz_date < DATE_ADD(#{cutoffDate}, INTERVAL 1 DAY)
|
||||
<include refid="arBillCutoffDateCondition"/>
|
||||
and p.ar_bill_status in
|
||||
<foreach collection="arBillStatuses" item="status" open="(" separator="," close=")">
|
||||
#{status}
|
||||
@@ -676,7 +688,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{excludedBillId}
|
||||
</foreach>
|
||||
</if>
|
||||
order by p.biz_date, p.order_no, p.bill_id
|
||||
<choose>
|
||||
<when test="dateType != null and dateType == 'PICKUP_DATE'">
|
||||
order by p.pickup_date, p.order_no, p.bill_id
|
||||
</when>
|
||||
<otherwise>
|
||||
order by p.biz_date, p.order_no, p.bill_id
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
|
||||
<select id="sumPrcOrderBillIncomeByCustomerPeriod" resultType="java.math.BigDecimal">
|
||||
@@ -704,7 +723,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
and p.biz_date < DATE_ADD(#{cutoffDate}, INTERVAL 1 DAY)
|
||||
<include refid="arBillCutoffDateCondition"/>
|
||||
and p.ar_bill_status in
|
||||
<foreach collection="arBillStatuses" item="status" open="(" separator="," close=")">
|
||||
#{status}
|
||||
@@ -720,7 +739,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
and p.customer_code like concat('%', #{customerCode}, '%')
|
||||
</if>
|
||||
<include refid="orderIdentifierCondition"/>
|
||||
and p.biz_date < DATE_ADD(#{cutoffDate}, INTERVAL 1 DAY)
|
||||
<include refid="arBillCutoffDateCondition"/>
|
||||
and p.ar_bill_status in
|
||||
<foreach collection="arBillStatuses" item="status" open="(" separator="," close=")">
|
||||
#{status}
|
||||
@@ -783,7 +802,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<select id="selectPrcOrderBillByCustomerCutoffAndIds" resultMap="PrcOrderBillArSourceResult">
|
||||
<include refid="selectArBillSourceVo"/>
|
||||
where p.customer_id = #{customerId}
|
||||
and p.biz_date < DATE_ADD(#{cutoffDate}, INTERVAL 1 DAY)
|
||||
<include refid="arBillCutoffDateCondition"/>
|
||||
and p.ar_bill_status in
|
||||
<foreach collection="arBillStatuses" item="status" open="(" separator="," close=")">
|
||||
#{status}
|
||||
@@ -800,7 +819,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="currency != null and currency != ''">
|
||||
and p.currency = #{currency}
|
||||
</if>
|
||||
order by p.biz_date, p.order_no, p.bill_id
|
||||
<choose>
|
||||
<when test="dateType != null and dateType == 'PICKUP_DATE'">
|
||||
order by p.pickup_date, p.order_no, p.bill_id
|
||||
</when>
|
||||
<otherwise>
|
||||
order by p.biz_date, p.order_no, p.bill_id
|
||||
</otherwise>
|
||||
</choose>
|
||||
</select>
|
||||
|
||||
<insert id="insertPrcOrderBill" parameterType="PrcOrderBill">
|
||||
|
||||
Reference in New Issue
Block a user