|
|
@@ -1,56 +1,215 @@
|
|
|
package com.ydtech.modules.partner;
|
|
|
|
|
|
-
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.ydtech.modules.partner.dao.PartnerPremiumDetailsMapper;
|
|
|
+import com.ydtech.modules.partner.dao.PartnerUserMapper;
|
|
|
import com.ydtech.modules.partner.model.PartnerCommissionRules;
|
|
|
+import com.ydtech.modules.partner.model.PartnerPremiumDetails;
|
|
|
+import com.ydtech.modules.partner.model.PartnerRatio;
|
|
|
+import com.ydtech.modules.partner.model.param.CommissionValidityPeriod;
|
|
|
import com.ydtech.modules.partner.model.vo.CommissionRulesVo;
|
|
|
+import com.ydtech.modules.partner.model.vo.PartnerRulesRatio;
|
|
|
import com.ydtech.modules.partner.service.PartnerCommissionService;
|
|
|
+import com.ydtech.modules.partner.service.PartnerUserService;
|
|
|
import com.ydtech.utils.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
-
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import javax.annotation.PostConstruct;
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.time.*;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Component
|
|
|
public class CalculateCommissionUtils {
|
|
|
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(CalculateCommissionUtils.class);
|
|
|
|
|
|
- private static PartnerCommissionService commissionService;
|
|
|
+ private static PartnerCommissionService commissionService;
|
|
|
+ private static PartnerUserMapper partnerUserMapper;
|
|
|
+ private static PartnerPremiumDetailsMapper partnerPremiumDetailsMapper;
|
|
|
+ private static PartnerUserService partnerUserService;
|
|
|
|
|
|
@Autowired
|
|
|
- public void setCommissionService(PartnerCommissionService commissionService) {
|
|
|
- this.commissionService = commissionService;
|
|
|
+ public void setCommissionService(PartnerCommissionService commissionService,
|
|
|
+ PartnerUserMapper partnerUserMapper,
|
|
|
+ PartnerPremiumDetailsMapper partnerPremiumDetailsMapper,
|
|
|
+ PartnerUserService partnerUserService) {
|
|
|
+ CalculateCommissionUtils.commissionService = commissionService;
|
|
|
+ CalculateCommissionUtils.partnerUserMapper = partnerUserMapper;
|
|
|
+ CalculateCommissionUtils.partnerPremiumDetailsMapper = partnerPremiumDetailsMapper;
|
|
|
+ CalculateCommissionUtils.partnerUserService = partnerUserService;
|
|
|
}
|
|
|
|
|
|
+ @PostConstruct
|
|
|
+ public void init() {
|
|
|
+ }
|
|
|
|
|
|
-
|
|
|
- public static BigDecimal calculateCommission(String grade) {
|
|
|
+ public static BigDecimal calculateCommission(String grade, String userId) {
|
|
|
CommissionRulesVo rulesVo = commissionService.queryAll();
|
|
|
- if (StringUtils.equals("1",grade)){
|
|
|
+ if (rulesVo == null) return BigDecimal.ZERO;
|
|
|
+ BigDecimal gl = ladderCommission(StringUtils.equals("3", grade) ? "2" : grade,
|
|
|
+ rulesVo.getAdministrator().getRulesRatioList(),
|
|
|
+ StringUtils.equals("3", grade) ? partnerUserMapper.queryReferrerId(userId) : userId,
|
|
|
+ rulesVo.getAdministrator());
|
|
|
+ BigDecimal hh = ladderCommission(StringUtils.equals("4", grade) ? "3" : grade,
|
|
|
+ rulesVo.getPartner().getRulesRatioList(),
|
|
|
+ StringUtils.equals("4", grade) ? partnerUserMapper.queryReferrerId(userId) : userId,
|
|
|
+ rulesVo.getPartner());
|
|
|
+ if (StringUtils.equals("1", grade)) {
|
|
|
return new BigDecimal(rulesVo.getOriginator());
|
|
|
}
|
|
|
- if (StringUtils.equals("2",grade)){
|
|
|
+ if (StringUtils.equals("2", grade)) {
|
|
|
PartnerCommissionRules administrator = rulesVo.getAdministrator();
|
|
|
- return new BigDecimal(administrator.getDefaultRatio());
|
|
|
+ if (isZero(gl) && isZero(hh)) {
|
|
|
+ return subtractRatios(administrator.getSharedRatio(), administrator.getDefaultRatio())
|
|
|
+ .add(subtractRatios(rulesVo.getPartner().getSharedRatio(), rulesVo.getPartner().getDefaultRatio()));
|
|
|
+ } else if (isZero(hh)) {
|
|
|
+ return new BigDecimal(administrator.getSharedRatio()).subtract(gl)
|
|
|
+ .add(subtractRatios(rulesVo.getPartner().getSharedRatio(), rulesVo.getPartner().getDefaultRatio()));
|
|
|
+ } else if (isZero(gl)) {
|
|
|
+ return new BigDecimal(rulesVo.getPartner().getSharedRatio()).subtract(hh)
|
|
|
+ .add(subtractRatios(administrator.getSharedRatio(), administrator.getDefaultRatio()));
|
|
|
+ }
|
|
|
}
|
|
|
- if (StringUtils.equals("3",grade)){
|
|
|
- PartnerCommissionRules administrator = rulesVo.getAdministrator();
|
|
|
- String sharedRatio = administrator.getSharedRatio();
|
|
|
- String defaultRatio = administrator.getDefaultRatio();
|
|
|
- BigDecimal subtract = new BigDecimal(sharedRatio).subtract(new BigDecimal(defaultRatio));
|
|
|
+ if (StringUtils.equals("3", grade)) {
|
|
|
PartnerCommissionRules partner = rulesVo.getPartner();
|
|
|
- String defaultRatio1 = partner.getDefaultRatio();
|
|
|
- return subtract.add(new BigDecimal(defaultRatio1));
|
|
|
+ if (isZero(gl) && isZero(hh)) {
|
|
|
+ return new BigDecimal(partner.getDefaultRatio())
|
|
|
+ .add(subtractRatios(rulesVo.getAdministrator().getSharedRatio(), rulesVo.getAdministrator().getDefaultRatio()));
|
|
|
+ } else if (isZero(hh)) {
|
|
|
+ return new BigDecimal(rulesVo.getAdministrator().getSharedRatio())
|
|
|
+ .subtract(new BigDecimal(rulesVo.getAdministrator().getDefaultRatio()))
|
|
|
+ .add(new BigDecimal(partner.getDefaultRatio()));
|
|
|
+ } else if (isZero(gl)) {
|
|
|
+ return new BigDecimal(partner.getSharedRatio()).subtract(hh)
|
|
|
+ .add(subtractRatios(rulesVo.getAdministrator().getSharedRatio(), rulesVo.getAdministrator().getDefaultRatio()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (StringUtils.equals("4", grade)) {
|
|
|
+ return isZero(hh) ? subtractRatios(rulesVo.getPartner().getSharedRatio(), rulesVo.getPartner().getDefaultRatio()) : hh;
|
|
|
}
|
|
|
- if (StringUtils.equals("4",grade)){
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
|
|
|
- PartnerCommissionRules partner = rulesVo.getPartner();
|
|
|
- String defaultRatio1 = partner.getDefaultRatio();
|
|
|
- String sharedRatio = partner.getSharedRatio();
|
|
|
- return new BigDecimal(sharedRatio).subtract(new BigDecimal(defaultRatio1));
|
|
|
+ private static boolean isZero(BigDecimal value) {
|
|
|
+ return value.compareTo(BigDecimal.ZERO) == 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static BigDecimal subtractRatios(String a, String b) {
|
|
|
+ return new BigDecimal(a).subtract(new BigDecimal(b));
|
|
|
+ }
|
|
|
+
|
|
|
+ public static BigDecimal ladderCommission(String grade, List<PartnerRulesRatio> rulesRatioList, String userId, PartnerCommissionRules rules) {
|
|
|
+ if (CollectionUtil.isEmpty(rulesRatioList) || StringUtils.equals("1", grade)) {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ CommissionValidityPeriod period = getCommissionValidityPeriod(rules, userId, grade);
|
|
|
+ List<PartnerRulesRatio> sortedList = rulesRatioList.stream()
|
|
|
+ .sorted(Comparator.comparing(PartnerRulesRatio::getKickback).reversed())
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ Set<String> userIdList = getUserIdList(userId);
|
|
|
+ BigDecimal sumPremium = BigDecimal.ZERO;
|
|
|
+ if (CollectionUtil.isNotEmpty(userIdList)) {
|
|
|
+ try {
|
|
|
+ QueryWrapper<PartnerPremiumDetails> queryWrapper = new QueryWrapper<>();
|
|
|
+ queryWrapper.in("user_id", userIdList);
|
|
|
+ if (StringUtils.isNotEmpty(period.getStartDate()) && StringUtils.isNotEmpty(period.getEndDate())) {
|
|
|
+ queryWrapper.between("create_time", period.getStartDate(), period.getEndDate());
|
|
|
+ }
|
|
|
+ BigDecimal totalSumPremium = partnerPremiumDetailsMapper.selectTotalSumPremium(queryWrapper);
|
|
|
+ sumPremium = Optional.ofNullable(totalSumPremium).orElse(BigDecimal.ZERO);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("查询保费失败", e);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ Integer number;
|
|
|
+ switch (grade) {
|
|
|
+ case "2":
|
|
|
+ number = partnerUserMapper.selectNumber(userId, "4", period);
|
|
|
+ break;
|
|
|
+ case "3":
|
|
|
+ number = partnerUserMapper.selectNumber(userId, "5", period);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return BigDecimal.ZERO;
|
|
|
+ }
|
|
|
+ BigDecimal numberBD = BigDecimal.valueOf(number);
|
|
|
+ for (PartnerRulesRatio ratio : sortedList) {
|
|
|
+ int allSatisfied = ratio.getAllSatisfied();
|
|
|
+ List<PartnerRatio> ratioList = ratio.getPartnerRatioList();
|
|
|
+ if (CollectionUtil.isEmpty(ratioList)) continue;
|
|
|
+
|
|
|
+ BigDecimal min = ratioList.get(0).getMin();
|
|
|
+ if (allSatisfied == 1) {
|
|
|
+ if (numberBD.compareTo(min) >= 0 && sumPremium.compareTo(min) >= 0) {
|
|
|
+ return ratio.getKickback();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (numberBD.compareTo(min) >= 0 || sumPremium.compareTo(min) >= 0) {
|
|
|
+ return ratio.getKickback();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
return BigDecimal.ZERO;
|
|
|
}
|
|
|
|
|
|
+ public static CommissionValidityPeriod getCommissionValidityPeriod(PartnerCommissionRules rules, String userId, String grade) {
|
|
|
+ CommissionValidityPeriod period = new CommissionValidityPeriod();
|
|
|
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ Date assessmentTime = partnerUserMapper.selectAssessmentTime(userId, grade);
|
|
|
+ if (assessmentTime == null) {
|
|
|
+ partnerUserMapper.updateAssessmentTime(userId);
|
|
|
+ assessmentTime = partnerUserMapper.selectAssessmentTime(userId, grade);
|
|
|
+ if (assessmentTime == null) return period;
|
|
|
+ }
|
|
|
+ if (StringUtils.equals("1", rules.getValidityPeriod())) {
|
|
|
+ return period;
|
|
|
+ } else if (StringUtils.equals("2", rules.getValidityPeriod())) {
|
|
|
+ if (isAfterNDays(assessmentTime, rules.getFixedDays())) {
|
|
|
+ if (isAfterNDays(assessmentTime, rules.getFixedDays() * 2)) {
|
|
|
+ partnerUserMapper.updateAssessmentTimeByDate(userId, new Date());
|
|
|
+ } else {
|
|
|
+ Date date = addDays(assessmentTime, rules.getFixedDays());
|
|
|
+ partnerUserMapper.updateAssessmentTimeByDate(userId, date);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ period.setStartDate(dateFormat.format(assessmentTime));
|
|
|
+ period.setEndDate(dateFormat.format(addDays(assessmentTime, rules.getFixedDays())));
|
|
|
+ }
|
|
|
+ } else if (StringUtils.equals("3", rules.getValidityPeriod())) {
|
|
|
+ period.setStartDate(rules.getStartDate());
|
|
|
+ period.setEndDate(rules.getEndDate());
|
|
|
+ }
|
|
|
+ return period;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static boolean isAfterNDays(Date targetDate, int days) {
|
|
|
+ LocalDateTime targetDateTime = targetDate.toInstant()
|
|
|
+ .atZone(ZoneId.systemDefault())
|
|
|
+ .toLocalDateTime();
|
|
|
+ LocalDateTime currentDateTime = LocalDateTime.now();
|
|
|
+ LocalDateTime nDaysLater = currentDateTime.plusDays(days);
|
|
|
+ return targetDateTime.isAfter(nDaysLater);
|
|
|
+ }
|
|
|
|
|
|
+ public static Date addDays(Date date, int days) {
|
|
|
+ LocalDateTime localDate = date.toInstant()
|
|
|
+ .atZone(ZoneId.systemDefault())
|
|
|
+ .toLocalDateTime();
|
|
|
+ LocalDateTime newLocalDate = localDate.plusDays(days);
|
|
|
+ return Date.from(newLocalDate.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ }
|
|
|
|
|
|
+ public static Set<String> getUserIdList(String userId) {
|
|
|
+ Set<String> list = new HashSet<>();
|
|
|
+ partnerUserService.getLevelUserId(userId, list);
|
|
|
+ return list;
|
|
|
+ }
|
|
|
}
|