Browse Source

政策排序重构

contract
Yen 2 years ago
parent
commit
6510a55390
  1. 63
      src/main/java/com/qs/serve/modules/tzc/common/dto/PolicySortWrapper.java
  2. 137
      src/main/java/com/qs/serve/modules/tzc/common/util/PolicySortWrapperUtil.java
  3. 29
      src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java

63
src/main/java/com/qs/serve/modules/tzc/common/dto/PolicySortWrapper.java

@ -0,0 +1,63 @@
package com.qs.serve.modules.tzc.common.dto;
import com.qs.serve.common.util.CollectionUtil;
import com.qs.serve.modules.tbs.entity.TbsBudget;
import com.qs.serve.modules.tbs.entity.TbsBudgetCondition;
import com.qs.serve.modules.tbs.entity.TbsScheduleItemBudget;
import lombok.Data;
import java.util.*;
import java.util.stream.Collectors;
/**
* 用于排序
* @author YenHex
* @since 2023/5/18
*/
@Data
public class PolicySortWrapper {
Set<Long> budgetSet4Subject = new HashSet<>();
Set<Long> budgetSet4NoSubject = new HashSet<>();
Set<Long> budgetSet4Condition = new HashSet<>();
Set<Long> budgetSet4NoCondition = new HashSet<>();
Map<Long,List<TbsBudgetCondition>> policyItemCostConditionsOfSort = new HashMap<>();
Map<Long,List<Long>> policyItemAllowBudgetId;
/**
* sort of timeline,filter timeline
* key is policy_item_id, value is schedule list
*/
Map<Long,List<TbsScheduleItemBudget>> policyItemScheduleItemMap = new HashMap<>();
public void putPolicyItemCondition(Long policyItemId, List<TbsBudgetCondition> list){
policyItemCostConditionsOfSort.put(policyItemId, list);
}
/**
* 初始化科目排序因子
* @param budgetList
*/
public void initializeBudget(List<TbsBudget> budgetList){
if(CollectionUtil.isNotEmpty(budgetList)){
for (TbsBudget budget : budgetList) {
if(budget.getSubjectId()==null||budget.getSubjectId().equals(0L)){
budgetSet4NoSubject.add(budget.getId());
}else {
budgetSet4Subject.add(budget.getId());
}
if(budget.getConditionFlag()==null||budget.getConditionFlag().equals(0)){
budgetSet4NoCondition.add(budget.getId());
}else {
budgetSet4Condition.add(budget.getId());
}
}
}
}
}

137
src/main/java/com/qs/serve/modules/tzc/common/util/PolicySortWrapperUtil.java

@ -0,0 +1,137 @@
package com.qs.serve.modules.tzc.common.util;
import com.qs.serve.common.util.Assert;
import com.qs.serve.common.util.CollectionUtil;
import com.qs.serve.modules.tbs.entity.TbsBudgetCondition;
import com.qs.serve.modules.tbs.entity.TbsScheduleItemBudget;
import com.qs.serve.modules.tzc.common.dto.PolicySortWrapper;
import com.qs.serve.modules.tzc.entity.TzcPolicyItem;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 用于排序
* @author YenHex
* @since 2023/5/18
*/
@Slf4j
@Data
public class PolicySortWrapperUtil {
public static List<TbsScheduleItemBudget> initializeSort(TzcPolicyItem policyItem, List<TbsScheduleItemBudget> list, PolicySortWrapper wrapper){
List<TbsScheduleItemBudget> resultSortList = new ArrayList<>();
if(CollectionUtil.isNotEmpty(list)){
//1.科目限制>品类之间>时间区间
//2.相同品类,取纬度最小值
//3.时间区间内,区间长度取最短
//3.时间区间内,区间长度相同,取最近结束时间
List<TbsScheduleItemBudget> tmpList4Subject = new ArrayList<>();
List<TbsScheduleItemBudget> tmpList4NotSubject = new ArrayList<>();
for (TbsScheduleItemBudget scheduleItemBudget : list) {
Long budgetId = scheduleItemBudget.getBudgetId();
if(wrapper.getBudgetSet4Subject().contains(budgetId)){
tmpList4Subject.add(scheduleItemBudget);
}else{
tmpList4NotSubject.add(scheduleItemBudget);
}
}
log.debug("政策项【{}】匹配有科目预算数:{},无科目预算:{}",policyItem.getPolicyItemCode() ,tmpList4Subject.size() , tmpList4NotSubject.size());
if(CollectionUtil.isNotEmpty(tmpList4Subject)){
PolicySortWrapperUtil.sort4Condition(policyItem,tmpList4Subject,resultSortList,wrapper);
}
if(CollectionUtil.isNotEmpty(tmpList4NotSubject)){
PolicySortWrapperUtil.sort4Condition(policyItem,tmpList4NotSubject,resultSortList,wrapper);
}
}
if(resultSortList.size()!=list.size()){
log.error("排序有误");
Assert.throwEx("排序有误");
}
return resultSortList;
}
/**
* 按有无条件分割
* @param policyItem
* @param list
* @param result
* @param wrapper
*/
private static void sort4Condition(TzcPolicyItem policyItem,List<TbsScheduleItemBudget> list,List<TbsScheduleItemBudget> result,PolicySortWrapper wrapper) {
List<TbsScheduleItemBudget> tmpList4Condition = new ArrayList<>();
List<TbsScheduleItemBudget> tmpList4NoCondition = new ArrayList<>();
for (TbsScheduleItemBudget scheduleItemBudget : list) {
Long budgetId = scheduleItemBudget.getBudgetId();
if(wrapper.getBudgetSet4Condition().contains(budgetId)){
tmpList4Condition.add(scheduleItemBudget);
}else{
tmpList4NoCondition.add(scheduleItemBudget);
}
}
log.debug("活动【{}】匹配有科目预算数:{},无科目预算:{}",policyItem.getPolicyItemCode() ,tmpList4Condition.size() , tmpList4NoCondition.size());
if(CollectionUtil.isNotEmpty(tmpList4Condition)){
PolicySortWrapperUtil.sort4GoodsCondition(policyItem,tmpList4Condition,result,wrapper);
}
if(CollectionUtil.isNotEmpty(tmpList4NoCondition)){
PolicySortWrapperUtil.sort4NotGoodsCondition(tmpList4NoCondition,result,wrapper);
}
}
private static void sort4GoodsCondition(TzcPolicyItem policyItem,List<TbsScheduleItemBudget> list,List<TbsScheduleItemBudget> result,PolicySortWrapper wrapper){
if(CollectionUtil.isNotEmpty(list)){
List<TbsBudgetCondition> activityCostConditions = wrapper.getPolicyItemCostConditionsOfSort().get(policyItem.getId());
Collections.sort(activityCostConditions, (o1, o2) -> {
int len1 = o1.getTargetLevelPathIds().split("_").length;
int len2 = o2.getTargetLevelPathIds().split("_").length;
if(len1==len2){
List<TbsScheduleItemBudget> scheduleItemBudgets = list;
Long day1 = null;
Long day2 = null;
for (TbsScheduleItemBudget itemBudget : scheduleItemBudgets) {
if(itemBudget.getBudgetId().equals(o1.getBudgetId())){
day1 = Duration.between(itemBudget.getStartDate(), itemBudget.getEndDate()).toDays();
}else if (itemBudget.getBudgetId().equals(o2.getBudgetId())){
day2 = Duration.between(itemBudget.getStartDate(), itemBudget.getEndDate()).toDays();
}
}
log.debug("活动【{}】 时间区间相同,day1:{} , day2:{}",policyItem.getPolicyItemCode(),day1,day2);
if(day1!=null&&day2!=null){
return (int) (day1-day2);
}
}
return len2 - len1;
});
List<TbsScheduleItemBudget> newSortList = new ArrayList<>();
for (TbsBudgetCondition costCondition : activityCostConditions) {
for (TbsScheduleItemBudget scheduleItemBudget : list) {
if(scheduleItemBudget.getBudgetId().equals(costCondition.getBudgetId())){
newSortList.add(scheduleItemBudget);
}
}
}
if(newSortList.size()!=list.size()){
log.error("排序有误");
Assert.throwEx("排序有误");
}
result.addAll(newSortList);
}
}
private static void sort4NotGoodsCondition(List<TbsScheduleItemBudget> list,List<TbsScheduleItemBudget> result,PolicySortWrapper wrapper){
if(CollectionUtil.isNotEmpty(list)){
Collections.sort(list, (o1, o2) -> {
Long day1 = Duration.between(o1.getStartDate(), o1.getEndDate()).toDays();
Long day2 = Duration.between(o2.getStartDate(), o2.getEndDate()).toDays();
log.debug("时间区间相同,day1:{} , day2:{}",day1,day2);
return (int) (day1-day2);
});
result.addAll(list);
}
}
}

29
src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java

@ -19,6 +19,8 @@ import com.qs.serve.modules.sys.service.SysConfigService;
import com.qs.serve.modules.sys.service.SysUserService; import com.qs.serve.modules.sys.service.SysUserService;
import com.qs.serve.modules.tbs.common.TbsGoodsType; import com.qs.serve.modules.tbs.common.TbsGoodsType;
import com.qs.serve.modules.tbs.common.TbsSeeYonConst; import com.qs.serve.modules.tbs.common.TbsSeeYonConst;
import com.qs.serve.modules.tbs.common.dto.CostSortWrapper;
import com.qs.serve.modules.tbs.common.util.CostSortWrapperUtil;
import com.qs.serve.modules.tbs.common.util.TbsBudgetCostUtil; import com.qs.serve.modules.tbs.common.util.TbsBudgetCostUtil;
import com.qs.serve.modules.tbs.common.util.TbsBudgetLogBuildUtil; import com.qs.serve.modules.tbs.common.util.TbsBudgetLogBuildUtil;
import com.qs.serve.modules.tbs.entity.*; import com.qs.serve.modules.tbs.entity.*;
@ -30,6 +32,8 @@ import com.qs.serve.modules.tbs.mapper.TbsScheduleItemBudgetMapper;
import com.qs.serve.modules.tbs.service.*; import com.qs.serve.modules.tbs.service.*;
import com.qs.serve.modules.tzc.common.TzPolicyItemStatus; import com.qs.serve.modules.tzc.common.TzPolicyItemStatus;
import com.qs.serve.modules.tzc.common.TzcPolicyStatus; import com.qs.serve.modules.tzc.common.TzcPolicyStatus;
import com.qs.serve.modules.tzc.common.dto.PolicySortWrapper;
import com.qs.serve.modules.tzc.common.util.PolicySortWrapperUtil;
import com.qs.serve.modules.tzc.entity.TzcPolicy; import com.qs.serve.modules.tzc.entity.TzcPolicy;
import com.qs.serve.modules.tzc.entity.TzcPolicyGoods; import com.qs.serve.modules.tzc.entity.TzcPolicyGoods;
import com.qs.serve.modules.tzc.entity.TzcPolicyItem; import com.qs.serve.modules.tzc.entity.TzcPolicyItem;
@ -349,12 +353,13 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
Boolean overspend, Boolean overspend,
Boolean throwEx, Boolean throwEx,
Boolean buildTableFlag){ Boolean buildTableFlag){
PolicySortWrapper sortWrapper = new PolicySortWrapper();
//考核期有关的预算id,判断逻辑为活动需要允许在 //考核期有关的预算id,判断逻辑为活动需要允许在
List<Long> budgetIds = new ArrayList<>(); List<Long> budgetIds = new ArrayList<>();
//没有预算的活动 //没有预算的活动
Set<Long> noBudgetPolicyIds = new HashSet<>(); Set<Long> noBudgetPolicyIds = new HashSet<>();
//所有满足条件的考核期,用于加载历史核销费用,并设置不满足时间条件的预算 //所有满足条件的考核期,用于加载历史核销费用,并设置不满足时间条件的预算
List<TbsScheduleItemBudget> scheduleItemList = this.loadScheduleBudgetAndSetting(policyItemList, budgetIds, noBudgetPolicyIds); List<TbsScheduleItemBudget> scheduleItemList = this.loadScheduleBudgetAndSetting(policyItemList, budgetIds, noBudgetPolicyIds,sortWrapper);
List<String> centerIds = policyItemList.stream().map(TzcPolicyItem::getCenterId).collect(Collectors.toList()); List<String> centerIds = policyItemList.stream().map(TzcPolicyItem::getCenterId).collect(Collectors.toList());
//默认为随货折让 //默认为随货折让
//List<Long> subjectIds = policyItemList.stream().map(TzcPolicyItem::getSubjectId).distinct().collect(Collectors.toList()); //List<Long> subjectIds = policyItemList.stream().map(TzcPolicyItem::getSubjectId).distinct().collect(Collectors.toList());
@ -371,11 +376,12 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
}else { }else {
budgetList = new ArrayList<>(); budgetList = new ArrayList<>();
} }
sortWrapper.initializeBudget(budgetList);
List<TbsBudget> noConditionBudgetList = new ArrayList<>(); List<TbsBudget> noConditionBudgetList = new ArrayList<>();
//加载预算条件和关联预算匹配,返回是否由无条件预算 //加载预算条件和关联预算匹配,返回是否由无条件预算
boolean budgetNoCondition = budgetApplicationService.loadConditionByBudgetsAndMatch(budgetList, noConditionBudgetList); boolean budgetNoCondition = budgetApplicationService.loadConditionByBudgetsAndMatch(budgetList, noConditionBudgetList);
//预算条件需包含活动条件, Map结构:政策id->满足的预算id列表 //预算条件需包含活动条件, Map结构:政策id->满足的预算id列表
Map<Long,List<Long>> policyAllowBudgetIdMap = this.buildPolicyBudgetMap(policyItemList, budgetList, noConditionBudgetList); Map<Long,List<Long>> policyAllowBudgetIdMap = this.buildPolicyBudgetMap(policyItemList, budgetList, noConditionBudgetList,sortWrapper);
//活动拦截 //活动拦截
if(!budgetNoCondition){ if(!budgetNoCondition){
this.handleNoBudgetPolicy(throwEx, overspend, policyItemList,noBudgetPolicyIds,policyAllowBudgetIdMap); this.handleNoBudgetPolicy(throwEx, overspend, policyItemList,noBudgetPolicyIds,policyAllowBudgetIdMap);
@ -411,8 +417,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
final List<TbsBudgetItemCostResult> actUnMatchList = new ArrayList<>(); final List<TbsBudgetItemCostResult> actUnMatchList = new ArrayList<>();
for (TzcPolicyItem policyItem : policyItemList) { for (TzcPolicyItem policyItem : policyItemList) {
this.matchPolicyMain(policyItem,throwEx,overspend,budgetItemAmountMap,budgetList, this.matchPolicyMain(policyItem,throwEx,overspend,budgetItemAmountMap,budgetList,
noConditionBudgetList,counterMap,actMatchList, noConditionBudgetList,counterMap,actMatchList, actUnMatchList,
actUnMatchList,policyAllowBudgetIdMap,budgetItemApplyAmountMap); policyAllowBudgetIdMap,budgetItemApplyAmountMap,sortWrapper);
} }
List<TbsBudgetCostItemPolicy> budgetMatchList = actMatchList.stream() List<TbsBudgetCostItemPolicy> budgetMatchList = actMatchList.stream()
.map(TbsBudgetItemCostResult::toBudgetCostItem).collect(Collectors.toList()); .map(TbsBudgetItemCostResult::toBudgetCostItem).collect(Collectors.toList());
@ -535,7 +541,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
final List<TbsBudgetItemCostResult> actMatchList, final List<TbsBudgetItemCostResult> actMatchList,
final List<TbsBudgetItemCostResult> actUnMatchList, final List<TbsBudgetItemCostResult> actUnMatchList,
final Map<Long,List<Long>> allowBudgetIdMap, final Map<Long,List<Long>> allowBudgetIdMap,
Map<Long,BigDecimal> budgetItemApplyAmountMap) { Map<Long,BigDecimal> budgetItemApplyAmountMap,
PolicySortWrapper sortWrapper ) {
TbsBudgetItemCostResult budgetItemCostResult = new TbsBudgetItemCostResult(); TbsBudgetItemCostResult budgetItemCostResult = new TbsBudgetItemCostResult();
budgetItemCostResult.setPolicyItem(policyItem); budgetItemCostResult.setPolicyItem(policyItem);
//过滤满全条件的预算 //过滤满全条件的预算
@ -579,6 +586,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
} }
} }
} }
//进行排序
currentScheduleItemBudgets = PolicySortWrapperUtil.initializeSort(policyItem,currentScheduleItemBudgets,sortWrapper);
//检测是否有是否足够预算 //检测是否有是否足够预算
BigDecimal goodsAmount = policyItem.getDiscountMax(); BigDecimal goodsAmount = policyItem.getDiscountMax();
if(CollectionUtil.isNotEmpty(currentScheduleItemBudgets)){ if(CollectionUtil.isNotEmpty(currentScheduleItemBudgets)){
@ -726,7 +735,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
*/ */
private Map<Long, List<Long>> buildPolicyBudgetMap(List<TzcPolicyItem> policyItemList, private Map<Long, List<Long>> buildPolicyBudgetMap(List<TzcPolicyItem> policyItemList,
List<TbsBudget> budgetList, List<TbsBudget> budgetList,
List<TbsBudget> noConditionBudgetList) { List<TbsBudget> noConditionBudgetList,
PolicySortWrapper sortWrapper) {
Map<Long, List<Long>> activityAllowBudgetIdMap = new HashMap<>(); Map<Long, List<Long>> activityAllowBudgetIdMap = new HashMap<>();
for (TzcPolicyItem policyItem : policyItemList) { for (TzcPolicyItem policyItem : policyItemList) {
Long policyItemId = policyItem.getId(); Long policyItemId = policyItem.getId();
@ -759,6 +769,7 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
} }
budgetIds.add(budget.getId()); budgetIds.add(budget.getId());
budgetIds.addAll(budgetIdsOfActivity); budgetIds.addAll(budgetIdsOfActivity);
sortWrapper.putPolicyItemCondition(policyItemId, budgetConditionList);
activityAllowBudgetIdMap.put(policyItemId,budgetIds); activityAllowBudgetIdMap.put(policyItemId,budgetIds);
} }
}else { }else {
@ -785,10 +796,12 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
* @return scheduleItemList 命中的考核期列表 * @return scheduleItemList 命中的考核期列表
*/ */
public List<TbsScheduleItemBudget> loadScheduleBudgetAndSetting(List<TzcPolicyItem> policyItemList, public List<TbsScheduleItemBudget> loadScheduleBudgetAndSetting(List<TzcPolicyItem> policyItemList,
List<Long> budgetIds, Set<Long> noBudgetPolicyItemIds) { List<Long> budgetIds, Set<Long> noBudgetPolicyItemIds,PolicySortWrapper sortWrapper) {
List<TbsScheduleItemBudget> scheduleItemList = new ArrayList<>(); List<TbsScheduleItemBudget> scheduleItemList = new ArrayList<>();
Set<Long> budgetIdsSet = new HashSet<>(); Set<Long> budgetIdsSet = new HashSet<>();
Map<Long,TbsScheduleItemBudget> allAllowScheduleItemTempMap = new HashMap<>(); Map<Long,TbsScheduleItemBudget> allAllowScheduleItemTempMap = new HashMap<>();
// of sort
Map<Long,List<TbsScheduleItemBudget>> scheduleItemMapOfSort = new HashMap<>();
for (TzcPolicyItem policyItem : policyItemList) { for (TzcPolicyItem policyItem : policyItemList) {
List<TbsScheduleItemBudget> budgetItemList = tbsScheduleItemBudgetService List<TbsScheduleItemBudget> budgetItemList = tbsScheduleItemBudgetService
.betweenDateList(policyItem.getPolicyStartDate(),policyItem.getPolicyEndDate()); .betweenDateList(policyItem.getPolicyStartDate(),policyItem.getPolicyEndDate());
@ -799,6 +812,7 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
budgetIdsSet.add(item.getBudgetId()); budgetIdsSet.add(item.getBudgetId());
allAllowScheduleItemTempMap.put(item.getId(),item); allAllowScheduleItemTempMap.put(item.getId(),item);
} }
scheduleItemMapOfSort.put(policyItem.getId(),budgetItemList);
}else { }else {
noBudgetPolicyItemIds.add(policyItem.getId()); noBudgetPolicyItemIds.add(policyItem.getId());
} }
@ -806,6 +820,7 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ
for (Long tmpId : allAllowScheduleItemTempMap.keySet()) { for (Long tmpId : allAllowScheduleItemTempMap.keySet()) {
scheduleItemList.add(allAllowScheduleItemTempMap.get(tmpId)); scheduleItemList.add(allAllowScheduleItemTempMap.get(tmpId));
} }
sortWrapper.setPolicyItemScheduleItemMap(scheduleItemMapOfSort);
budgetIds.addAll(budgetIdsSet); budgetIds.addAll(budgetIdsSet);
return scheduleItemList; return scheduleItemList;
} }

Loading…
Cancel
Save