## 注册、升级、复购等添加秒结业绩处理;188安置关系按实时业绩左右区进行安置;

This commit is contained in:
cabbage 2025-07-21 17:28:36 +08:00
parent f31110ff50
commit 305117aba6
19 changed files with 205 additions and 262 deletions

View File

@ -87,9 +87,4 @@ public class BonusConfigDTO implements Serializable {
*/
private Map<String, BdBonusService> bonusServiceMap;
/**
* 云代奖金 需要主键 国家+收益类型
*/
private Map<String, BdBonusCloud> bonusCloudMap;
}

View File

@ -1,12 +0,0 @@
package com.hzs.bonus.bonus.service.impl;
import org.springframework.stereotype.Component;
/**
* 计算云代奖金
*/
@Component
public class BonusSettleAgentHandle extends BonusSettleHandle {
}

View File

@ -1153,8 +1153,9 @@ public abstract class BonusSettleHandle {
}
/**
* 根据订单分类分为首购复购真实获取新增业绩
*
* @param orderExtList 订单列表
* @Description: 根据订单分类分为首购复购真实获取新增业绩
*/
public void assortSaOrder(Map<Long, MemberAchieveParam> cuMemberAchieveHashMap, List<SaOrderExt> orderExtList,
BonusConfigDTO bonusConfigDTO, Boolean isFirst) {

View File

@ -1,12 +0,0 @@
package com.hzs.bonus.bonus.service.impl;
import org.springframework.stereotype.Component;
/**
* 计算嗨粉订单
*/
@Component
public class BonusSettleHiFunHandle extends BonusSettleHandle {
}

View File

@ -172,7 +172,8 @@ public class BonusSettlePurchaseHandle extends BonusSettleHandle {
}
/**
* @Description: 秒接复购量奖
* 秒接复购量奖
*
* @return: List<CuMemberBonusExpand>
*/
protected List<CuMemberBonusExpand> calculateRepurchaseExpandSecondBonus(Map<Long, CuMemberRiskControl> riskControlMap, String settleTableName, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO,
@ -185,7 +186,8 @@ public class BonusSettlePurchaseHandle extends BonusSettleHandle {
}
/**
* @Description: 秒接复购量奖
* 秒接复购量奖
*
* @return: List<CuMemberBonusExpand>
*/
protected List<CuMemberBonusPush> calculateRepurchasePushSecondBonus(String settleTableName, Map<Long, CuMemberSettleExt> cuMemberSettleExtMap, BonusConfigDTO bonusConfigDTO, Integer period,

View File

@ -139,10 +139,6 @@ public class BonusSettleServiceImpl implements IBonusSettleService {
@Autowired
private BonusSettleNewExpandHandle bonusSettleNewExpandHandle;
@Autowired
private BonusSettleHiFunHandle bonusSettleHiFunHandle;
@Autowired
private BonusSettleAgentHandle bonusSettleAgentHandle;
@Autowired
private BonusSettleRepCouponsHandle bonusSettleRepCouponsHandle;
@Autowired
private BonusSettleMallHandle bonusSettleMallHandle;
@ -155,27 +151,34 @@ public class BonusSettleServiceImpl implements IBonusSettleService {
public void calculateCumberBonusBySecond(String orderCode) {
log.info("开始执行秒接,订单编号:{}", orderCode);
Date startDate = DateUtils.currentDate();
SaOrderExt saOrderExt = iSaOrderServiceApi.querySaOrderByDay(startDate,
DateUtils.afterDate(1, ChronoUnit.DAYS, startDate), orderCode).getData();
SaOrderExt saOrderExt = iSaOrderServiceApi.querySaOrderByDay(startDate, DateUtils.afterDate(1, ChronoUnit.DAYS, startDate), orderCode).getData();
log.info("查询订单,订单参数:{}", JSONUtil.toJsonStr(saOrderExt));
Map<String, String> systemConfigMap = iSystemConfigServiceApi.getBonusSystemConfig().getData();
Map<String, RangeDTO> rangeDtoMap = iRangeServiceApi.queryRangeDto().getData();
// 处理奖金结算秒结表判断是否存在当天结算的秒接表从cu_member中获取网体从昨日结算表中获取累计结余数据
String settleDate = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, saOrderExt.getPayTime());
String beforeDay = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(1, ChronoUnit.DAYS, saOrderExt.getPayTime()));
String beforeYesDay = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.beforeDate(2, ChronoUnit.DAYS, saOrderExt.getPayTime()));
int period = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(settleDate).getPkId();
int beforePeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeDay).getPkId();
int beforeYesPeriod = iCuMemberSettlePeriodService.getCuMemberSettlePeriodByDate(beforeYesDay).getPkId();
log.info("查询订单,订单参数:{}", JSONUtil.toJsonStr(saOrderExt));
// 今天秒结表
String secondTableName = TableNameConstants.CU_MEMBER_SECOND + period;
// 昨天日结表
String settleTableName = TableNameConstants.CU_MEMBER_SETTLE + beforePeriod;
// 前天
// 前天日结表
String yesSettleTableName = TableNameConstants.CU_MEMBER_SETTLE + beforeYesPeriod;
Map<Long, CuMemberBonus> cuMemberBonusMap = new HashMap<>(MagicNumberConstants.DELETE_DATA_BATCH_UPDATE_NUM);
BonusConfigDTO bonusConfigDTO = iBonusItemsServiceApi.queryBonusConfigDTO().getData();
Map<Long, CuMemberSettleExt> cuMemberSettleExtMap = new HashMap<>();
Map<Long, CuAwardsControl> cuAwardsControlMap = getCuAwardsControlMap();
List<BdAwards> awardsList = iAwardsServiceApi.queryAwards(saOrderExt.getPkCountry()).getData();
// 计算奖金
if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType() ||
EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType() ||
@ -195,117 +198,176 @@ public class BonusSettleServiceImpl implements IBonusSettleService {
memberList.add(cuMember.getPkCenterCode());
}
getSettleMember(saOrderExt, secondTableName, settleTableName, yesSettleTableName, memberList);
// 查询出上面的网体数据
// 查询出上面的网体数据推荐
List<CuMemberSettleExt> cuMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondParent(secondTableName, memberList);
bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
// 计算奖金
// 计算直推奖
List<GradeDTO> gradeDtoList = iGradeServiceApi.queryGradeConfigByCondition(saOrderExt.getPkCountry()).getData();
CuMemberBonusPush cuMemberBonusPush = bonusSettleFirstPurchaseHandle.calculatePushBonusOne(cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, cuMemberBonusMap, saOrderExt, iAwardsServiceApi.getAwards().getData(), gradeDtoList);
log.info("获得直推奖,奖金为:{}", JSONUtil.toJsonStr(cuMemberBonusPush));
// 计算量奖
// 所有需要计算的父节点只计算新增
// 所有需要计算的父节点安置只计算新增
List<CuMemberSettleExt> expandMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondPlaceParent(secondTableName, saOrderExt.getPkMember());
bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, expandMemberSettleExtList);
Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
Map<Long, CuMemberAssess> cuMemberAssessMap = bonusSettleFirstPurchaseHandle.getLongCuMemberAssessMap(settleDate, expandMemberSettleExtList);
// 查询K值控制
List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
for (CuMemberSettleExt cuMemberSettleExt : expandMemberSettleExtList) {
// 数据已经准备好了肯定有值map中是实际的值先计算新增然后根据新增结算计算碰次list是为了存储碰次的顺序
CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberSettleExt.getPkPlaceParent());
if (null == targetMemberSettleExt
|| ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory()
|| EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()
|| EGrade.START_UP.getValue() == targetMemberSettleExt.getGradeValue()) {
// 会员不满足计算奖金条件跳过
continue;
}
Map<Long, CuBonusExpandExt> cuBonusExpandExtMap = new HashMap<>();
BonusExpandParam bonusExpandParam = BonusExpandParam.builder().settleDate(DateUtils.parseStringToDate(settleDate)).build();
List<CuBonusExpandExt> cuBonusExpandExtList = iCuBonusExpandService.queryBonusExpand(bonusExpandParam);
cuBonusExpandExtList.forEach(cuBonusExpandExt -> cuBonusExpandExtMap.put(cuBonusExpandExt.getPkMember(), cuBonusExpandExt));
BigDecimal addTouch = BigDecimal.ZERO;
for (int i = expandMemberSettleExtList.size() - 1; i >= 0; i--) {
CuMemberSettleExt cuMemberSettleExt = cuMemberSettleExtList.get(i);
if (cuBonusExpandExtMap.containsKey(cuMemberSettleExt.getPkMember())) {
addTouch = cuBonusExpandExtMap.get(cuMemberSettleExt.getPkMember()).getAddTouch();
break;
if (EPlaceDept.LEFT_DEPT.getValue() == cuMemberSettleExt.getPlaceDept()) {
// 左区
targetMemberSettleExt.setANewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getANewAmount(), saOrderExt.getOrderAmount()));
targetMemberSettleExt.setANewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getANewPv(), saOrderExt.getUploadAchieve()));
targetMemberSettleExt.setABalance(ComputeUtil.computeAdd(targetMemberSettleExt.getABalance(), saOrderExt.getUploadAchieve()));
} else {
// 右区
targetMemberSettleExt.setBNewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewAmount(), saOrderExt.getOrderAmount()));
targetMemberSettleExt.setBNewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewPv(), saOrderExt.getUploadAchieve()));
targetMemberSettleExt.setBBalance(ComputeUtil.computeAdd(targetMemberSettleExt.getBBalance(), saOrderExt.getUploadAchieve()));
}
}
List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettleFirstPurchaseHandle.calculateExpandBonusOne(riskControlMap, cuMemberAssessMap, settleTableName, cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, expandMemberSettleExtList, saOrderExt, false, addTouch, BigDecimal.ZERO, 0);
// 计算领导奖
Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(1);
saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt);
// 领导奖现在首购复购都有此处需要传入参数区分
boolean firstFlag = EOrderType.SPECIAL_REGISTER_ORDER.getValue() == saOrderExt.getOrderType()
|| EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType();
// 领导奖处理
List<CuMemberBonusCoach> cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonusOne(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO,
cuMemberBonusExpandList, period, cuMemberBonusMap, saOrderExtMap, cuAwardsControlMap, riskControlMap, awardsList, firstFlag, false);
// 计算报单服务费
CuMemberBonusDetail cuMemberBonusDetail = bonusSettleFirstPurchaseHandle.calculateServiceBonusOne(settleDate, cuMemberAssessMap, cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExt);
// 复购券
List<CuMemberBonusDetail> couponsBonusDetailList = bonusSettleRepCouponsHandle.calculateRepurchaseCoupons(startDate, Collections.singletonList(saOrderExt), period, bonusConfigDTO, cuMemberBonusMap, cuMemberSettleExtMap);
saveCuMemberBonus(period, settleDate, cuMemberBonusMap);
cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId());
Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
iCuMemberBonusPushService.insertCuMemberBonusPush(cuMemberBonusPush);
cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(cuMemberBonusExpandList, memberIdSet);
cuMemberBonusCoachList.forEach(cuMemberBonusCoach ->
cuMemberBonusCoach.setPkBonus(cuMemberBonusMap.get(cuMemberBonusCoach.getPkBonus()).getPkId()));
iCuMemberBonusCoachService.batchInsertCuMemberBonusCoach(cuMemberBonusCoachList, memberIdSet);
List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
if (cuMemberBonusDetail != null) {
cuMemberBonusDetailList.add(cuMemberBonusDetail);
}
if (CollectionUtil.isNotEmpty(couponsBonusDetailList)) {
cuMemberBonusDetailList.addAll(couponsBonusDetailList);
}
if (cuMemberBonusDetailList.size() > 0) {
cuMemberBonusDetailList.forEach(bonusDetail ->
bonusDetail.setPkBonus(cuMemberBonusMap.get(bonusDetail.getPkBonus()).getPkId()));
iCuMemberBonusDetailService.batchInsertCuMemberBonusDetail(cuMemberBonusDetailList, memberIdSet);
}
// // 计算奖金
// // 计算直推奖
// List<GradeDTO> gradeDtoList = iGradeServiceApi.queryGradeConfigByCondition(saOrderExt.getPkCountry()).getData();
// CuMemberBonusPush cuMemberBonusPush = bonusSettleFirstPurchaseHandle.calculatePushBonusOne(cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, cuMemberBonusMap, saOrderExt, iAwardsServiceApi.getAwards().getData(), gradeDtoList);
// log.info("获得直推奖,奖金为:{}", JSONUtil.toJsonStr(cuMemberBonusPush));
// // 计算量奖
// // 所有需要计算的父节点只计算新增
// List<CuMemberSettleExt> expandMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondPlaceParent(secondTableName, saOrderExt.getPkMember());
// bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, expandMemberSettleExtList);
// Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
// Map<Long, CuMemberAssess> cuMemberAssessMap = bonusSettleFirstPurchaseHandle.getLongCuMemberAssessMap(settleDate, expandMemberSettleExtList);
// // 查询K值控制
// List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
// Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
// if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
// cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
// }
// Map<Long, CuBonusExpandExt> cuBonusExpandExtMap = new HashMap<>();
// BonusExpandParam bonusExpandParam = BonusExpandParam.builder().settleDate(DateUtils.parseStringToDate(settleDate)).build();
// List<CuBonusExpandExt> cuBonusExpandExtList = iCuBonusExpandService.queryBonusExpand(bonusExpandParam);
// cuBonusExpandExtList.forEach(cuBonusExpandExt -> cuBonusExpandExtMap.put(cuBonusExpandExt.getPkMember(), cuBonusExpandExt));
// BigDecimal addTouch = BigDecimal.ZERO;
// for (int i = expandMemberSettleExtList.size() - 1; i >= 0; i--) {
// CuMemberSettleExt cuMemberSettleExt = cuMemberSettleExtList.get(i);
// if (cuBonusExpandExtMap.containsKey(cuMemberSettleExt.getPkMember())) {
// addTouch = cuBonusExpandExtMap.get(cuMemberSettleExt.getPkMember()).getAddTouch();
// break;
// }
// }
// // 计算首购量奖
// List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettleFirstPurchaseHandle.calculateExpandBonusOne(riskControlMap, cuMemberAssessMap, settleTableName, cuMemberSettleExtMap,
// bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, expandMemberSettleExtList, saOrderExt, false, addTouch, BigDecimal.ZERO, 0);
// // 计算领导奖
// Map<Long, SaOrderExt> saOrderExtMap = new HashMap<>(1);
// saOrderExtMap.put(saOrderExt.getPkId(), saOrderExt);
//
// // 领导奖现在首购复购都有此处需要传入参数区分
// boolean firstFlag = EOrderType.SPECIAL_REGISTER_ORDER.getValue() == saOrderExt.getOrderType()
// || EOrderType.SPECIAL_UPGRADE_ORDER.getValue() == saOrderExt.getOrderType();
// // 领导奖处理
// List<CuMemberBonusCoach> cuMemberBonusCoachList = bonusSettleFirstPurchaseHandle.calculateCoachBonusOne(cuMemberSettleExtMap, settleTableName, settleDate, bonusConfigDTO,
// cuMemberBonusExpandList, period, cuMemberBonusMap, saOrderExtMap, cuAwardsControlMap, riskControlMap, awardsList, firstFlag, false);
//
// // 计算报单服务费
// CuMemberBonusDetail cuMemberBonusDetail = bonusSettleFirstPurchaseHandle.calculateServiceBonusOne(settleDate, cuMemberAssessMap, cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExt);
// // 复购券
// List<CuMemberBonusDetail> couponsBonusDetailList = bonusSettleRepCouponsHandle.calculateRepurchaseCoupons(startDate, Collections.singletonList(saOrderExt), period, bonusConfigDTO, cuMemberBonusMap, cuMemberSettleExtMap);
// saveCuMemberBonus(period, settleDate, cuMemberBonusMap);
// cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId());
// Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
// iCuMemberBonusPushService.insertCuMemberBonusPush(cuMemberBonusPush);
// cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
// cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
// iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(cuMemberBonusExpandList, memberIdSet);
//
// cuMemberBonusCoachList.forEach(cuMemberBonusCoach ->
// cuMemberBonusCoach.setPkBonus(cuMemberBonusMap.get(cuMemberBonusCoach.getPkBonus()).getPkId()));
// iCuMemberBonusCoachService.batchInsertCuMemberBonusCoach(cuMemberBonusCoachList, memberIdSet);
//
// List<CuMemberBonusDetail> cuMemberBonusDetailList = new ArrayList<>();
// if (cuMemberBonusDetail != null) {
// cuMemberBonusDetailList.add(cuMemberBonusDetail);
// }
// if (CollectionUtil.isNotEmpty(couponsBonusDetailList)) {
// cuMemberBonusDetailList.addAll(couponsBonusDetailList);
// }
// if (cuMemberBonusDetailList.size() > 0) {
// cuMemberBonusDetailList.forEach(bonusDetail ->
// bonusDetail.setPkBonus(cuMemberBonusMap.get(bonusDetail.getPkBonus()).getPkId()));
// iCuMemberBonusDetailService.batchInsertCuMemberBonusDetail(cuMemberBonusDetailList, memberIdSet);
// }
log.info("首购奖金计算完毕");
} else {
// 先处理关系
List<Long> memberList = new ArrayList<>();
getSettleMember(saOrderExt, secondTableName, yesSettleTableName, settleTableName, memberList);
// 初始化需要秒接结算的数据
// 查询出上面的网体数据推荐
List<CuMemberSettleExt> pushMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondParent(secondTableName, memberList);
bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, pushMemberSettleExtList);
List<CuMemberBonusPush> cuMemberBonusPushList = bonusSettlePurchaseHandle.calculateRepurchasePushSecondBonus(settleTableName, cuMemberSettleExtMap, bonusConfigDTO, period, cuMemberBonusMap, saOrderExt, pushMemberSettleExtList, settleDate);
// 查询出上面的网体数据
List<CuMemberSettleExt> cuMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondPlaceParent(secondTableName, saOrderExt.getPkMember());
bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, cuMemberSettleExtList);
Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
// 复购订单计算复购推荐 复购极差复购拓展
// 查询K值控制
List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
// 所有需要计算的父节点安置只计算新增
List<CuMemberSettleExt> expandMemberSettleExtList = iCuMemberTreeService.queryCuMemberSecondPlaceParent(secondTableName, saOrderExt.getPkMember());
bonusSettleFirstPurchaseHandle.getSecondMemberSettle(cuMemberSettleExtMap, expandMemberSettleExtList);
for (CuMemberSettleExt cuMemberSettleExt : expandMemberSettleExtList) {
// 数据已经准备好了肯定有值map中是实际的值先计算新增然后根据新增结算计算碰次list是为了存储碰次的顺序
CuMemberSettleExt targetMemberSettleExt = cuMemberSettleExtMap.get(cuMemberSettleExt.getPkPlaceParent());
if (null == targetMemberSettleExt
|| ECategory.NORMAL.getValue() != targetMemberSettleExt.getCategory()
|| EAccountStatus.STOP_INCOME.getValue() == targetMemberSettleExt.getAccountStatus()
|| EGrade.START_UP.getValue() == targetMemberSettleExt.getGradeValue()) {
// 会员不满足计算奖金条件跳过
continue;
}
List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettlePurchaseHandle.calculateRepurchaseExpandSecondBonus(riskControlMap, settleTableName,
cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, saOrderExt, cuMemberSettleExtList, settleDate, BigDecimal.ZERO, BigDecimal.ZERO, 0);
// c)增加奖衔记录表
Map<String, BdAwards> awardsMap = iAwardsServiceApi.getAwards().getData();
List<CuMemberBonusRange> cuMemberBonusRangeList = bonusSettlePurchaseHandle.calculateRepurchaseRangeBonus(cuMemberSettleExtMap, settleTableName, settleDate, rangeDtoMap, awardsMap,
bonusConfigDTO, Collections.singletonList(saOrderExt), period, cuMemberBonusMap, cuAwardsControlMap);
if (cuMemberBonusMap.size() > 0) {
saveCuMemberBonus(period, settleDate, cuMemberBonusMap);
Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
cuMemberBonusPushList.forEach(cuMemberBonusPush ->
cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId()));
iCuMemberBonusPushService.batchInsertCuMemberBonusPush(cuMemberBonusPushList, memberIdSet);
cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(cuMemberBonusExpandList, memberIdSet);
cuMemberBonusRangeList.forEach(cuMemberBonusRange ->
cuMemberBonusRange.setPkBonus(cuMemberBonusMap.get(cuMemberBonusRange.getPkBonus()).getPkId()));
iCuMemberBonusRangeService.batchInsertCuMemberBonusRange(cuMemberBonusRangeList, memberIdSet);
if (EPlaceDept.LEFT_DEPT.getValue() == cuMemberSettleExt.getPlaceDept()) {
// 左区
targetMemberSettleExt.setANewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getANewAmount(), saOrderExt.getOrderAmount()));
targetMemberSettleExt.setANewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getANewPv(), saOrderExt.getUploadAchieve()));
targetMemberSettleExt.setABalance(ComputeUtil.computeAdd(targetMemberSettleExt.getABalance(), saOrderExt.getUploadAchieve()));
} else {
// 右区
targetMemberSettleExt.setBNewAmount(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewAmount(), saOrderExt.getOrderAmount()));
targetMemberSettleExt.setBNewPv(ComputeUtil.computeAdd(targetMemberSettleExt.getBNewPv(), saOrderExt.getUploadAchieve()));
targetMemberSettleExt.setBBalance(ComputeUtil.computeAdd(targetMemberSettleExt.getBBalance(), saOrderExt.getUploadAchieve()));
}
}
// // 秒接复购量奖
// List<CuMemberBonusPush> cuMemberBonusPushList = bonusSettlePurchaseHandle.calculateRepurchasePushSecondBonus(settleTableName, cuMemberSettleExtMap,
// bonusConfigDTO, period, cuMemberBonusMap, saOrderExt, pushMemberSettleExtList, settleDate);
// Map<Long, CuMemberBonus> weekMemberBonusMap = getWeekMemberBonusMap(settleDate, period);
// // 复购订单计算复购推荐 复购极差复购拓展
// // 查询K值控制
// List<CuMemberRiskControl> cuMemberRiskControlList = iCuMemberRiskControlService.queryCuMemberRiskControl(DateUtils.parseStringToDate(settleDate));
// Map<Long, CuMemberRiskControl> riskControlMap = new HashMap<>();
// if (CollectionUtil.isNotEmpty(cuMemberRiskControlList)) {
// cuMemberRiskControlList.forEach(cuMemberRiskControl -> riskControlMap.put(cuMemberRiskControl.getPkMember(), cuMemberRiskControl));
// }
// // 计算复购量奖
// List<CuMemberBonusExpand> cuMemberBonusExpandList = bonusSettlePurchaseHandle.calculateRepurchaseExpandSecondBonus(riskControlMap, settleTableName,
// cuMemberSettleExtMap, bonusConfigDTO, systemConfigMap, period, weekMemberBonusMap, cuMemberBonusMap, saOrderExt, cuMemberSettleExtList, settleDate, BigDecimal.ZERO, BigDecimal.ZERO, 0);
// // c)增加奖衔记录表
// Map<String, BdAwards> awardsMap = iAwardsServiceApi.getAwards().getData();
// List<CuMemberBonusRange> cuMemberBonusRangeList = bonusSettlePurchaseHandle.calculateRepurchaseRangeBonus(cuMemberSettleExtMap, settleTableName, settleDate, rangeDtoMap, awardsMap,
// bonusConfigDTO, Collections.singletonList(saOrderExt), period, cuMemberBonusMap, cuAwardsControlMap);
// if (cuMemberBonusMap.size() > 0) {
// saveCuMemberBonus(period, settleDate, cuMemberBonusMap);
// Set<Long> memberIdSet = iCuMemberBonusService.queryMemberBonusByPeriod(period);
// cuMemberBonusPushList.forEach(cuMemberBonusPush ->
// cuMemberBonusPush.setPkBonus(cuMemberBonusMap.get(cuMemberBonusPush.getPkBonus()).getPkId()));
// iCuMemberBonusPushService.batchInsertCuMemberBonusPush(cuMemberBonusPushList, memberIdSet);
// cuMemberBonusExpandList.forEach(cuMemberBonusExpand ->
// cuMemberBonusExpand.setPkBonus(cuMemberBonusMap.get(cuMemberBonusExpand.getPkBonus()).getPkId()));
// iCuMemberBonusExpandService.batchInsertCuMemberBonusExpand(cuMemberBonusExpandList, memberIdSet);
// cuMemberBonusRangeList.forEach(cuMemberBonusRange ->
// cuMemberBonusRange.setPkBonus(cuMemberBonusMap.get(cuMemberBonusRange.getPkBonus()).getPkId()));
// iCuMemberBonusRangeService.batchInsertCuMemberBonusRange(cuMemberBonusRangeList, memberIdSet);
// }
log.info("复购奖金计算完毕");
}
// 更新网体结构

View File

@ -19,7 +19,7 @@ import org.springframework.stereotype.Component;
public class SaOrderSecondListener {
@Autowired
private IBonusSettleService bonusSettleService;
private IBonusSettleService iBonusSettleService;
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange(value = RabbitMqConstants.ORDER_SECOND_EXCHANGE, type = "topic"),
@ -28,13 +28,14 @@ public class SaOrderSecondListener {
@RabbitHandler
public void onMessage(Message<SaOrderExt> message, Channel channel) throws Exception {
SaOrderExt saOrderExt = message.getPayload();
log.info("秒结开始消费,接收到的参数:{}", saOrderExt.getOrderCode());
Long deliveryTag = (Long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
channel.basicAck(deliveryTag, false);
log.info("秒结开始消费,接收到的参数:{}", saOrderExt.getOrderCode());
try {
Thread.sleep(500);
// 订单当日订单只计算奖衔
bonusSettleService.calculateCumberBonusBySecond(saOrderExt.getOrderCode());
iBonusSettleService.calculateCumberBonusBySecond(saOrderExt.getOrderCode());
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -593,21 +593,22 @@
<update id="updateCuMemberSecondPlaceParent">
merge into ${secondTableName} a
using (
select B.pk_id,b.pk_settle_country pk_country,nvl(st.A_BALANCE,0) A_BALANCE,nvl(st.B_BALANCE,0) B_BALANCE,
select B.pk_id, b.pk_settle_country pk_country,
nvl(st.A_BALANCE, 0) A_BALANCE, nvl(st.B_BALANCE, 0) B_BALANCE,
nvl(yt.A_SUM_AMOUNT,0) A_SUM_AMOUNT,nvl(yt.B_SUM_AMOUNT,0) B_SUM_AMOUNT,
nvl(yt.A_SUM_PV,0) A_SUM_PV,nvl(yt.b_SUM_PV,0) b_SUM_PV,nvl(st.A_NEW_AMOUNT,0) A_NEW_AMOUNT,
nvl(st.B_NEW_AMOUNT,0) B_NEW_AMOUNT,nvl(st.A_NEW_PV,0) A_NEW_PV,
nvl(ST.B_NEW_PV,0) B_NEW_PV,nvl(yt.A_SUM_REAL_AMOUNT,0) A_SUM_REAL_AMOUNT,
nvl(yt.B_SUM_REAL_AMOUNT,0) B_SUM_REAL_AMOUNT,
nvl(yt.A_SUM_REAL_PV,0) A_SUM_REAL_PV,
nvl(yt.B_SUM_REAL_PV,0) B_SUM_REAL_PV,
nvl(yt.A_SUM_REAL_PV,0) a_sum_real_pv, nvl(yt.B_SUM_REAL_PV,0) b_sum_real_pv,
nvl(ST.REP_A_BALANCE,0) REP_A_BALANCE,nvl(ST.REP_B_BALANCE,0) REP_B_BALANCE,
nvl(ST.REP_A_NEW_AMOUNT,0) REP_A_NEW_AMOUNT,
nvl(ST.REP_B_NEW_AMOUNT,0) REP_B_NEW_AMOUNT,nvl(ST.REP_A_NEW_PV,0) REP_A_NEW_PV,
nvl(ST.REP_B_NEW_PV,0) REP_B_NEW_PV,nvl(yt.REP_A_SUM_AMOUNT,0) REP_A_SUM_AMOUNT,
nvl(yt.REP_B_SUM_AMOUNT,0) REP_B_SUM_AMOUNT,nvl(yt.REP_A_SUM_PV,0) REP_A_SUM_PV,
nvl(yt.REP_B_SUM_PV,0) REP_B_SUM_PV,
nvl(ST.ROUND,0) ROUND,nvl(nvl(ST.SECOND,yt.second),1) SECOND,nvl(ST.MIN_ACHIEVE,0) MIN_ACHIEVE,b.expire_status
nvl(ST.ROUND,0) ROUND,nvl(nvl(ST.SECOND,yt.second),1) SECOND,nvl(ST.MIN_ACHIEVE,0) MIN_ACHIEVE,
b.expire_status
from
(select t.pk_id,t.pk_settle_country,t.expire_status from cu_member t
where t.del_flag = 0 start with t.pk_id = #{pkMember}
@ -628,7 +629,7 @@
left join ${secondTableName} st
on b.pk_id = st.pk_member
left join ${settleTableName} yt
on b.pk_id=yt.pk_member
on b.pk_id = yt.pk_member
) b
on (a.pk_member = b.pk_id)
when matched then

View File

@ -102,8 +102,8 @@ public class CuMemberAchieveServiceImpl extends ServiceImpl<CuMemberAchieveMappe
String currentTableName = TableNameConstants.CU_MEMBER_SECOND + currentPeriod;
CuMemberAchieve cuMemberAchieve = baseMapper.queryCuMemberAchieveByPkMember(pkMember, pkCountry, currentTableName);
if (cuMemberAchieve != null) {
if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberAchieve.getASumPv(), cuMemberAchieve.getBSumPv())) ||
ComputeUtil.compareValue(cuMemberAchieve.getRepASumPv(), cuMemberAchieve.getRepBSumPv())) {
if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberAchieve.getASumPv(), cuMemberAchieve.getBSumPv()))
|| ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberAchieve.getASumRealPv(), cuMemberAchieve.getBSumRealPv()))) {
return cuMemberAchieve;
}
}

View File

@ -479,7 +479,7 @@ public class ApiMemberController extends BaseController {
}
/**
* 查询推荐人编号
* 查询推荐人编号 -- 188分享注册
*
* @param pkParent 推荐人加密
* @return
@ -498,7 +498,7 @@ public class ApiMemberController extends BaseController {
}
/**
* 根据订单查询会员信息
* 根据订单查询会员信息 -- 188分享注册
*
* @param orderCode 订单编号
* @return

View File

@ -1275,9 +1275,9 @@ public class CuMemberBusinessServiceImpl implements ICuMemberBusinessService {
placeDept = EPlaceDept.RIGHT_DEPT.getValue();
}
} else {
// TODO 188判断左右区结余小区
if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberAchieve.getASumPv(), cuMemberAchieve.getBSumPv()))) {
if (ComputeUtil.compareValue(cuMemberAchieve.getASumPv(), cuMemberAchieve.getBSumPv())) {
// 188判断左右区真实业绩放入小区
if (ComputeUtil.compareValue(ComputeUtil.computeAdd(cuMemberAchieve.getASumRealPv(), cuMemberAchieve.getBSumRealPv()))) {
if (ComputeUtil.compareValue(cuMemberAchieve.getASumRealPv(), cuMemberAchieve.getBSumRealPv())) {
placeDept = EPlaceDept.RIGHT_DEPT.getValue();
}
} else {

View File

@ -90,7 +90,7 @@
REP_B_SUM_PV,
PK_COUNTRY
FROM ${tableName}
WHERE (pk_member = #{pkMember} AND pk_country = #{pkCountry})
WHERE pk_member = #{pkMember} AND pk_country = #{pkCountry}
</select>
<select id="selectNewAddAchieve" resultType="com.hzs.member.achieve.vo.CuMemberNewAddAchieveVO">

View File

@ -756,9 +756,8 @@ public class SaOrderServiceImpl extends ServiceImpl<SaOrderMapper, SaOrder> impl
try {
log.info("生产活动消息activity.exchange{}", JSONUtil.toJsonStr(saOrderExt));
rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);
// //计算奖金通过mq分发消息异步处理
// log.info("生产秒结消息order.second.exchange{}", JSONUtil.toJsonStr(saOrderExt));
// rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
// 推送秒结数据处理 -- 注册订单
rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
// if (EOrderType.REGISTER_ORDER.getValue() == saOrderExt.getOrderType()) {
// // 推送会员续约处理MQ
@ -863,8 +862,9 @@ public class SaOrderServiceImpl extends ServiceImpl<SaOrderMapper, SaOrder> impl
throw new RuntimeException("保存会员失败!!!");
}
try {
// rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
rabbitTemplate.convertAndSend(RabbitMqConstants.ACTIVITY_EXCHANGE, RabbitMqConstants.ACTIVITY_KEY, saOrderExt);
// 推送秒结数据处理 -- 升级订单
rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
// if (EOrderType.UPGRADE_ORDER.getValue() == saOrderExt.getOrderType()) {
// // 推送会员续约处理MQ
@ -953,6 +953,8 @@ public class SaOrderServiceImpl extends ServiceImpl<SaOrderMapper, SaOrder> impl
}
try {
// 推送秒结数据处理 -- 其它订单
rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
// if (EOrderType.RENEWAL_ORDER.getValue() == saOrderExt.getOrderType()) {
// // 续约专区推送MQ
// rabbitTemplate.convertAndSend(RabbitMqConstants.MEMBER_CONTINUE_EXCHANGE, RabbitMqConstants.MEMBER_CONTINUE_KEY,
@ -961,8 +963,6 @@ public class SaOrderServiceImpl extends ServiceImpl<SaOrderMapper, SaOrder> impl
// .eMemberContinue(EMemberContinue.BUY_GIFT)
// .build());
// }
// // 推送秒结数据
// rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_SECOND_EXCHANGE, RabbitMqConstants.ORDER_SECOND_KEY, saOrderExt);
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -1,17 +1,10 @@
package com.hzs.system.config.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hzs.common.domain.system.config.BdBonusCloud;
/**
* <p>
* 云代配置
Mapper 接口
* </p>
*
* @author zhangjing
* @since 2022-11-01
* 云代配置 Mapper 接口
*/
public interface BdBonusCloudMapper extends BaseMapper<BdBonusCloud> {

View File

@ -114,8 +114,6 @@ public class BonusItemsServiceProvider implements IBonusItemsServiceApi {
bonusConfigDTO.setBonusDeductsMap(getBonusDeductConfig());
// 报单服务费
bonusConfigDTO.setBonusServiceMap(getBonusServiceConfig());
// 云代奖金
bonusConfigDTO.setBonusCloudMap(getBonusCloudConfig());
return R.ok(bonusConfigDTO);
}
@ -276,15 +274,4 @@ public class BonusItemsServiceProvider implements IBonusItemsServiceApi {
return bdBonusDeductMap;
}
/**
* 获取每个国家奖金项对应的扣项
*/
private Map<String, BdBonusCloud> getBonusCloudConfig() {
List<BdBonusCloud> bonusCloudList = bdBonusCloudService.queryBdBonusCloud();
Map<String, BdBonusCloud> bdBonusCloudHashMap = new HashMap<>(ComputeUtil.mapInitCapacity(bonusCloudList.size()));
bonusCloudList.forEach(bdBonusCloud ->
bdBonusCloudHashMap.put(bdBonusCloud.getPkCountry().toString() + bdBonusCloud.getCloudType(), bdBonusCloud));
return bdBonusCloudHashMap;
}
}

View File

@ -1,45 +1,21 @@
package com.hzs.system.config.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hzs.common.domain.system.config.BdBonusCloud;
import com.hzs.common.domain.system.config.ext.BdBonusCloudExt;
import java.util.List;
/**
* <p>
* 云代配置
服务类
* </p>
*
* @author zhangjing
* @since 2022-11-01
* 云代配置 服务类
*/
public interface IBdBonusCloudService extends IService<BdBonusCloud> {
/*
* @description: 查询云代奖金配置
* @author: sui q
* @date: 2023/7/5 15:17
* @param: null null
**/
List<BdBonusCloud> queryBdBonusCloud();
/**
* @description: 新增云代配置
* @author: zhang jing
* @date: 2022/11/1 17:13
* @param: [bonusCloudExt]
* @return: boolean
* 新增云代配置
**/
boolean saveBonusCloud(BdBonusCloudExt bonusCloudExt);
/**
* @description: 修改云代配置
* @author: zhang jing
* @date: 2022/11/1 17:13
* @param: [bonusCloudExt]
* @return: boolean
* 修改云代配置
**/
boolean updateBonusCloud(BdBonusCloudExt bonusCloudExt);
}

View File

@ -1,6 +1,5 @@
package com.hzs.system.config.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.domain.system.config.BdBonusCloud;
@ -11,43 +10,22 @@ import com.hzs.system.config.service.IBdBonusCloudService;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* <p>
* 云代配置
服务实现类
* </p>
*
* @author zhangjing
* @since 2022-11-01
* 云代配置 服务实现类
*/
@Service
public class BdBonusCloudServiceImpl extends ServiceImpl<BdBonusCloudMapper, BdBonusCloud> implements IBdBonusCloudService {
@Override
public List<BdBonusCloud> queryBdBonusCloud() {
QueryWrapper<BdBonusCloud> queryWrapper = new QueryWrapper<>();
queryWrapper.select("CLOUD_TYPE,CLOUD_RATIO,PK_COUNTRY");
return baseMapper.selectList(queryWrapper);
}
/**
* @description: 新增云代配置
* @author: zhang jing
* @date: 2022/11/1 17:11
* @param: [bonusCloudExt]
* @return: boolean
**/
@Override
public boolean saveBonusCloud(BdBonusCloudExt bonusCloudExt) {
for(BdBonusCloud bonusCloud:bonusCloudExt.getBonusCloudList()){
for (BdBonusCloud bonusCloud : bonusCloudExt.getBonusCloudList()) {
bonusCloud.setPkCountry(SecurityUtils.getPkCountry());
if(StringUtils.isNotNull(bonusCloud.getPkId())){
if (StringUtils.isNotNull(bonusCloud.getPkId())) {
bonusCloud.setPkModified(SecurityUtils.getUserId());
bonusCloud.setModifiedTime(new Date());
baseMapper.updateById(bonusCloud);
}else{
} else {
bonusCloud.setPkCreator(SecurityUtils.getUserId());
bonusCloud.setCreationTime(new Date());
baseMapper.insert(bonusCloud);
@ -58,7 +36,7 @@ public class BdBonusCloudServiceImpl extends ServiceImpl<BdBonusCloudMapper, BdB
@Override
public boolean updateBonusCloud(BdBonusCloudExt bonusCloudExt) {
for(BdBonusCloud bonusCloud:bonusCloudExt.getBonusCloudList()){
for (BdBonusCloud bonusCloud : bonusCloudExt.getBonusCloudList()) {
bonusCloud.setPkCountry(SecurityUtils.getPkCountry());
bonusCloud.setPkModified(SecurityUtils.getUserId());
bonusCloud.setModifiedTime(new Date());

View File

@ -2,28 +2,5 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hzs.system.config.mapper.BdBonusCloudMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.hzs.common.domain.system.config.BdBonusCloud">
<id column="PK_ID" property="pkId" />
<result column="DEL_FLAG" property="delFlag" />
<result column="PK_COUNTRY" property="pkCountry" />
<result column="CREATION_TIME" property="creationTime" />
<result column="MODIFIED_TIME" property="modifiedTime" />
<result column="PK_CREATOR" property="pkCreator" />
<result column="PK_MODIFIED" property="pkModified" />
<result column="CLOUD_TYPE" property="cloudType" />
<result column="CLOUD_RATIO" property="cloudRatio" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
DEL_FLAG,
PK_COUNTRY,
CREATION_TIME,
MODIFIED_TIME,
PK_CREATOR,
PK_MODIFIED,
PK_ID, CLOUD_TYPE, CLOUD_RATIO
</sql>
</mapper>

View File

@ -14,13 +14,7 @@ import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* <p>
* 云代配置
* </p>
*
* @author zhangjing
* @since 2022-11-01
*/
@Data
@EqualsAndHashCode(callSuper = true)