From 6510a553907bb2ff2c95fb91a6d79c821252c8ce Mon Sep 17 00:00:00 2001 From: Yen Date: Mon, 5 Jun 2023 09:16:57 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=BF=E7=AD=96=E6=8E=92=E5=BA=8F=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tzc/common/dto/PolicySortWrapper.java | 63 ++++++++ .../common/util/PolicySortWrapperUtil.java | 137 ++++++++++++++++++ .../impl/TzcPolicyApplicationServiceImpl.java | 29 +++- 3 files changed, 222 insertions(+), 7 deletions(-) create mode 100644 src/main/java/com/qs/serve/modules/tzc/common/dto/PolicySortWrapper.java create mode 100644 src/main/java/com/qs/serve/modules/tzc/common/util/PolicySortWrapperUtil.java diff --git a/src/main/java/com/qs/serve/modules/tzc/common/dto/PolicySortWrapper.java b/src/main/java/com/qs/serve/modules/tzc/common/dto/PolicySortWrapper.java new file mode 100644 index 00000000..d2d6f849 --- /dev/null +++ b/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 budgetSet4Subject = new HashSet<>(); + Set budgetSet4NoSubject = new HashSet<>(); + + Set budgetSet4Condition = new HashSet<>(); + Set budgetSet4NoCondition = new HashSet<>(); + + + Map> policyItemCostConditionsOfSort = new HashMap<>(); + Map> policyItemAllowBudgetId; + + /** + * sort of timeline,filter timeline + * key is policy_item_id, value is schedule list + */ + Map> policyItemScheduleItemMap = new HashMap<>(); + + + public void putPolicyItemCondition(Long policyItemId, List list){ + policyItemCostConditionsOfSort.put(policyItemId, list); + } + + /** + * 初始化科目排序因子 + * @param budgetList + */ + public void initializeBudget(List 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()); + } + } + } + } + + +} diff --git a/src/main/java/com/qs/serve/modules/tzc/common/util/PolicySortWrapperUtil.java b/src/main/java/com/qs/serve/modules/tzc/common/util/PolicySortWrapperUtil.java new file mode 100644 index 00000000..1d677e60 --- /dev/null +++ b/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 initializeSort(TzcPolicyItem policyItem, List list, PolicySortWrapper wrapper){ + List resultSortList = new ArrayList<>(); + if(CollectionUtil.isNotEmpty(list)){ + //1.科目限制>品类之间>时间区间 + //2.相同品类,取纬度最小值 + //3.时间区间内,区间长度取最短 + //3.时间区间内,区间长度相同,取最近结束时间 + List tmpList4Subject = new ArrayList<>(); + List 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 list,List result,PolicySortWrapper wrapper) { + List tmpList4Condition = new ArrayList<>(); + List 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 list,List result,PolicySortWrapper wrapper){ + if(CollectionUtil.isNotEmpty(list)){ + List 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 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 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 list,List 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); + } + } + +} diff --git a/src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java b/src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java index 0f512849..1025dba3 100644 --- a/src/main/java/com/qs/serve/modules/tzc/service/impl/TzcPolicyApplicationServiceImpl.java +++ b/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.tbs.common.TbsGoodsType; 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.TbsBudgetLogBuildUtil; 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.tzc.common.TzPolicyItemStatus; 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.TzcPolicyGoods; import com.qs.serve.modules.tzc.entity.TzcPolicyItem; @@ -349,12 +353,13 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ Boolean overspend, Boolean throwEx, Boolean buildTableFlag){ + PolicySortWrapper sortWrapper = new PolicySortWrapper(); //考核期有关的预算id,判断逻辑为活动需要允许在 List budgetIds = new ArrayList<>(); //没有预算的活动 Set noBudgetPolicyIds = new HashSet<>(); //所有满足条件的考核期,用于加载历史核销费用,并设置不满足时间条件的预算 - List scheduleItemList = this.loadScheduleBudgetAndSetting(policyItemList, budgetIds, noBudgetPolicyIds); + List scheduleItemList = this.loadScheduleBudgetAndSetting(policyItemList, budgetIds, noBudgetPolicyIds,sortWrapper); List centerIds = policyItemList.stream().map(TzcPolicyItem::getCenterId).collect(Collectors.toList()); //默认为随货折让 //List subjectIds = policyItemList.stream().map(TzcPolicyItem::getSubjectId).distinct().collect(Collectors.toList()); @@ -371,11 +376,12 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ }else { budgetList = new ArrayList<>(); } + sortWrapper.initializeBudget(budgetList); List noConditionBudgetList = new ArrayList<>(); //加载预算条件和关联预算匹配,返回是否由无条件预算 boolean budgetNoCondition = budgetApplicationService.loadConditionByBudgetsAndMatch(budgetList, noConditionBudgetList); //预算条件需包含活动条件, Map结构:政策id->满足的预算id列表 - Map> policyAllowBudgetIdMap = this.buildPolicyBudgetMap(policyItemList, budgetList, noConditionBudgetList); + Map> policyAllowBudgetIdMap = this.buildPolicyBudgetMap(policyItemList, budgetList, noConditionBudgetList,sortWrapper); //活动拦截 if(!budgetNoCondition){ this.handleNoBudgetPolicy(throwEx, overspend, policyItemList,noBudgetPolicyIds,policyAllowBudgetIdMap); @@ -411,8 +417,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ final List actUnMatchList = new ArrayList<>(); for (TzcPolicyItem policyItem : policyItemList) { this.matchPolicyMain(policyItem,throwEx,overspend,budgetItemAmountMap,budgetList, - noConditionBudgetList,counterMap,actMatchList, - actUnMatchList,policyAllowBudgetIdMap,budgetItemApplyAmountMap); + noConditionBudgetList,counterMap,actMatchList, actUnMatchList, + policyAllowBudgetIdMap,budgetItemApplyAmountMap,sortWrapper); } List budgetMatchList = actMatchList.stream() .map(TbsBudgetItemCostResult::toBudgetCostItem).collect(Collectors.toList()); @@ -535,7 +541,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ final List actMatchList, final List actUnMatchList, final Map> allowBudgetIdMap, - Map budgetItemApplyAmountMap) { + Map budgetItemApplyAmountMap, + PolicySortWrapper sortWrapper ) { TbsBudgetItemCostResult budgetItemCostResult = new TbsBudgetItemCostResult(); budgetItemCostResult.setPolicyItem(policyItem); //过滤满全条件的预算 @@ -579,6 +586,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ } } } + //进行排序 + currentScheduleItemBudgets = PolicySortWrapperUtil.initializeSort(policyItem,currentScheduleItemBudgets,sortWrapper); //检测是否有是否足够预算 BigDecimal goodsAmount = policyItem.getDiscountMax(); if(CollectionUtil.isNotEmpty(currentScheduleItemBudgets)){ @@ -726,7 +735,8 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ */ private Map> buildPolicyBudgetMap(List policyItemList, List budgetList, - List noConditionBudgetList) { + List noConditionBudgetList, + PolicySortWrapper sortWrapper) { Map> activityAllowBudgetIdMap = new HashMap<>(); for (TzcPolicyItem policyItem : policyItemList) { Long policyItemId = policyItem.getId(); @@ -759,6 +769,7 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ } budgetIds.add(budget.getId()); budgetIds.addAll(budgetIdsOfActivity); + sortWrapper.putPolicyItemCondition(policyItemId, budgetConditionList); activityAllowBudgetIdMap.put(policyItemId,budgetIds); } }else { @@ -785,10 +796,12 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ * @return scheduleItemList 命中的考核期列表 */ public List loadScheduleBudgetAndSetting(List policyItemList, - List budgetIds, Set noBudgetPolicyItemIds) { + List budgetIds, Set noBudgetPolicyItemIds,PolicySortWrapper sortWrapper) { List scheduleItemList = new ArrayList<>(); Set budgetIdsSet = new HashSet<>(); Map allAllowScheduleItemTempMap = new HashMap<>(); + // of sort + Map> scheduleItemMapOfSort = new HashMap<>(); for (TzcPolicyItem policyItem : policyItemList) { List budgetItemList = tbsScheduleItemBudgetService .betweenDateList(policyItem.getPolicyStartDate(),policyItem.getPolicyEndDate()); @@ -799,6 +812,7 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ budgetIdsSet.add(item.getBudgetId()); allAllowScheduleItemTempMap.put(item.getId(),item); } + scheduleItemMapOfSort.put(policyItem.getId(),budgetItemList); }else { noBudgetPolicyItemIds.add(policyItem.getId()); } @@ -806,6 +820,7 @@ public class TzcPolicyApplicationServiceImpl implements TzcPolicyApplicationServ for (Long tmpId : allAllowScheduleItemTempMap.keySet()) { scheduleItemList.add(allAllowScheduleItemTempMap.get(tmpId)); } + sortWrapper.setPolicyItemScheduleItemMap(scheduleItemMapOfSort); budgetIds.addAll(budgetIdsSet); return scheduleItemList; }