✨ 支持按单号批量排除账单订单
This commit is contained in:
@@ -32,6 +32,8 @@ public class ArBillGenerateRequest
|
||||
private String selectionMode = ArBillSelectionMode.EXPLICIT.getCode();
|
||||
/** 全选模式中用户明确排除的来源订单 ID。 */
|
||||
private List<String> excludedSourceBillIds;
|
||||
/** 全选模式下按订单号、运单号或转单号排除;后台生成任务按批次应用该条件。 */
|
||||
private String excludedOrderOrTrackingNo;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
@JsonDeserialize(using = StrictDateDeserializer.class)
|
||||
private Date billDate;
|
||||
|
||||
@@ -8,7 +8,7 @@ public enum ArBillSelectionMode
|
||||
{
|
||||
/** 手动选择当前预览结果中的订单。 */
|
||||
EXPLICIT("EXPLICIT", "手动选择"),
|
||||
/** 选择全部查询结果,仅排除用户明确勾选的订单。 */
|
||||
/** 选择全部查询结果,再按用户提供的排除条件移除匹配订单。 */
|
||||
ALL_MATCHED("ALL_MATCHED", "全选查询结果");
|
||||
|
||||
private final String code;
|
||||
|
||||
@@ -37,6 +37,8 @@ public interface IArBillService
|
||||
|
||||
List<PrcOrderBill> previewBill(ArBillGenerateQuery query);
|
||||
|
||||
List<PrcOrderBill> previewExcludedBill(ArBillGenerateQuery query);
|
||||
|
||||
BigDecimal sumPreviewBill(ArBillGenerateQuery query);
|
||||
|
||||
ArBillGenerateTask generateBill(ArBillGenerateRequest request, String operator, String requestId);
|
||||
|
||||
@@ -299,6 +299,15 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
return result;
|
||||
}
|
||||
|
||||
/** 查询待排除的订单;必须带至少一个精确单号,避免空条件返回整个账单范围。 */
|
||||
@Override
|
||||
public List<PrcOrderBill> previewExcludedBill(ArBillGenerateQuery query) {
|
||||
if (query == null || normalizeOrderIdentifiers(query.getExcludeOrderOrTrackingNo()).isEmpty()) {
|
||||
throw new ServiceException("请输入订单号、运单号或转单号后再查询");
|
||||
}
|
||||
return previewBill(query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 汇总当前生成条件下的订单应收金额,用于弹窗顶部合计展示。
|
||||
*/
|
||||
@@ -358,8 +367,18 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
throw new ServiceException("全选模式最多排除 " + EXCLUDED_SOURCE_ID_LIMIT
|
||||
+ " 条订单,请缩小查询条件后再生成");
|
||||
}
|
||||
List<String> excludedOrderIdentifiers = allMatched
|
||||
? normalizeOrderIdentifiers(request.getExcludedOrderOrTrackingNo()) : new ArrayList<>();
|
||||
if (!allMatched) {
|
||||
request.setExcludedOrderOrTrackingNo(null);
|
||||
}
|
||||
int orderIdentifierCount = normalizeOrderIdentifiers(request.getOrderOrTrackingNo()).size()
|
||||
+ excludedOrderIdentifiers.size();
|
||||
if (orderIdentifierCount > ORDER_IDENTIFIER_LIMIT) {
|
||||
throw new ServiceException("筛选单号和排除单号合计最多输入 " + ORDER_IDENTIFIER_LIMIT + " 个");
|
||||
}
|
||||
validateOrderIdentifierParameterCount(
|
||||
normalizeOrderIdentifiers(request.getOrderOrTrackingNo()).size(),
|
||||
orderIdentifierCount,
|
||||
allMatched ? excludedSourceBillIds.size() : sourceBillIds.size());
|
||||
request.setSelectionMode(selectionMode);
|
||||
|
||||
@@ -535,6 +554,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
ArBillGenerateRequest request = JSON.parseObject(task.getRequestPayload(), ArBillGenerateRequest.class);
|
||||
List<String> sourceBillIds = normalizeSourceBillIds(request.getSourceBillIds());
|
||||
List<String> excludedSourceBillIds = normalizeSourceBillIds(request.getExcludedSourceBillIds());
|
||||
List<String> excludedOrderIdentifiers = ArBillSelectionMode.ALL_MATCHED.getCode().equals(task.getSelectionMode())
|
||||
? normalizeOrderIdentifiers(request.getExcludedOrderOrTrackingNo()) : new ArrayList<>();
|
||||
TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
|
||||
transactionTemplate.setTimeout(300);
|
||||
|
||||
@@ -544,8 +565,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
request.getCustomerId(), request.getCustomerCode(),
|
||||
normalizeOrderIdentifiers(request.getOrderOrTrackingNo()),
|
||||
request.getBillPeriodEnd(), request.getCurrency(), eligibleOrderBillStatuses(),
|
||||
ArIncomeBillFeeStatus.UNBILLED.getCode(),
|
||||
task.getSnapshotCreateTime(), null, excludedSourceBillIds);
|
||||
ArIncomeBillFeeStatus.UNBILLED.getCode(), task.getSnapshotCreateTime(), null,
|
||||
excludedSourceBillIds, excludedOrderIdentifiers);
|
||||
if (totalCount <= 0) {
|
||||
throw new ServiceException("当前全选范围内没有可生成的订单");
|
||||
}
|
||||
@@ -572,7 +593,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
}
|
||||
ArBillGenerateTask currentTask = task;
|
||||
GenerateBatchResult result = transactionTemplate.execute(status -> processGenerateBatch(
|
||||
currentTask, request, sourceBillIds, excludedSourceBillIds));
|
||||
currentTask, request, sourceBillIds, excludedSourceBillIds, excludedOrderIdentifiers));
|
||||
if (result == null || result.finished) {
|
||||
transactionTemplate.execute(status -> {
|
||||
completeGenerateTask(taskId);
|
||||
@@ -659,7 +680,8 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
* 每批最多 GENERATE_PAGE_SIZE 条,成功后原子更新任务进度。
|
||||
*/
|
||||
private GenerateBatchResult processGenerateBatch(ArBillGenerateTask task, ArBillGenerateRequest request,
|
||||
List<String> sourceBillIds, List<String> excludedSourceBillIds) {
|
||||
List<String> sourceBillIds, List<String> excludedSourceBillIds,
|
||||
List<String> excludedOrderIdentifiers) {
|
||||
ArBillSelectionMode selectionMode = ArBillSelectionMode.of(task.getSelectionMode());
|
||||
if (selectionMode == null) {
|
||||
throw new ServiceException("账单生成任务的订单选择模式无效");
|
||||
@@ -673,6 +695,7 @@ public class ArBillServiceImpl implements IArBillService {
|
||||
eligibleOrderBillStatuses(), ArIncomeBillFeeStatus.UNBILLED.getCode(),
|
||||
task.getSnapshotCreateTime(), task.getLastSourceBillId(),
|
||||
explicitIds, selectionMode == ArBillSelectionMode.ALL_MATCHED ? excludedSourceBillIds : null,
|
||||
selectionMode == ArBillSelectionMode.ALL_MATCHED ? excludedOrderIdentifiers : null,
|
||||
GENERATE_PAGE_SIZE);
|
||||
if (sources == null || sources.isEmpty()) {
|
||||
return new GenerateBatchResult(true);
|
||||
|
||||
@@ -68,14 +68,16 @@ public interface PrcOrderBillMapper
|
||||
@Param("arBillStatuses") List<String> arBillStatuses, @Param("feeArBillStatus") String feeArBillStatus,
|
||||
@Param("snapshotCreateTime") Date snapshotCreateTime,
|
||||
@Param("lastSourceBillId") String lastSourceBillId, @Param("billIds") List<String> billIds,
|
||||
@Param("excludedBillIds") List<String> excludedBillIds, @Param("limit") int limit);
|
||||
@Param("excludedBillIds") List<String> excludedBillIds,
|
||||
@Param("excludedOrderIdentifiers") List<String> excludedOrderIdentifiers, @Param("limit") int limit);
|
||||
|
||||
int countPrcOrderBillByCustomerPeriod(@Param("customerId") Long customerId,
|
||||
@Param("customerCode") String customerCode, @Param("orderIdentifiers") List<String> orderIdentifiers,
|
||||
@Param("cutoffDate") Date cutoffDate, @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);
|
||||
@Param("billIds") List<String> billIds, @Param("excludedBillIds") List<String> excludedBillIds,
|
||||
@Param("excludedOrderIdentifiers") List<String> excludedOrderIdentifiers);
|
||||
|
||||
/** 按生成账单时用户勾选的订单读取,并再次校验账单筛选条件。 */
|
||||
public List<PrcOrderBill> selectPrcOrderBillByCustomerCutoffAndIds(@Param("customerId") Long customerId,
|
||||
|
||||
@@ -693,6 +693,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
#{excludedBillId}
|
||||
</foreach>
|
||||
</if>
|
||||
<if test="excludedOrderIdentifiers != null and excludedOrderIdentifiers.size() > 0">
|
||||
and not (
|
||||
coalesce(p.order_no, '') in
|
||||
<foreach collection="excludedOrderIdentifiers" item="excludedIdentifier" open="(" separator="," close=")">
|
||||
#{excludedIdentifier}
|
||||
</foreach>
|
||||
or coalesce(p.tracking_no, '') in
|
||||
<foreach collection="excludedOrderIdentifiers" item="excludedIdentifier" open="(" separator="," close=")">
|
||||
#{excludedIdentifier}
|
||||
</foreach>
|
||||
or coalesce(p.transfer_no, '') in
|
||||
<foreach collection="excludedOrderIdentifiers" item="excludedIdentifier" open="(" separator="," close=")">
|
||||
#{excludedIdentifier}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
</sql>
|
||||
|
||||
<!-- 异步生成使用 bill_id 游标批量读取,避免深分页和一次加载全量订单。 -->
|
||||
|
||||
Reference in New Issue
Block a user