UpdateRatioUtils.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. package com.ydtech.modules.partner;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import cn.hutool.extra.spring.SpringUtil;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.ydtech.modules.partner.dao.PartnerPremiumDetailsMapper;
  6. import com.ydtech.modules.partner.dao.PartnerUserMapper;
  7. import com.ydtech.modules.partner.model.*;
  8. import com.ydtech.modules.partner.model.param.CommissionValidityPeriod;
  9. import com.ydtech.modules.partner.model.vo.CommissionRulesVo;
  10. import com.ydtech.modules.partner.model.vo.PartnerRulesRatio;
  11. import com.ydtech.modules.partner.service.PartnerCommissionService;
  12. import com.ydtech.modules.partner.service.PartnerKickbackChangeService;
  13. import com.ydtech.modules.partner.service.PartnerUserService;
  14. import com.ydtech.utils.StringUtils;
  15. import org.slf4j.Logger;
  16. import org.slf4j.LoggerFactory;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.stereotype.Component;
  19. import javax.annotation.PostConstruct;
  20. import java.math.BigDecimal;
  21. import java.util.*;
  22. import java.util.stream.Collectors;
  23. @Component
  24. public class UpdateRatioUtils {
  25. private static final Logger log = LoggerFactory.getLogger(UpdateRatioUtils.class);
  26. private static PartnerCommissionService commissionService;
  27. private static PartnerUserMapper partnerUserMapper;
  28. private static PartnerPremiumDetailsMapper partnerPremiumDetailsMapper;
  29. private static PartnerUserService partnerUserService;
  30. private static PartnerKickbackChangeService kickbackChangeService;
  31. @Autowired
  32. public void setCommissionService(PartnerCommissionService commissionService,
  33. PartnerUserMapper partnerUserMapper,
  34. PartnerKickbackChangeService kickbackChangeService,
  35. PartnerPremiumDetailsMapper partnerPremiumDetailsMapper,
  36. PartnerUserService partnerUserService) {
  37. UpdateRatioUtils.commissionService = commissionService;
  38. UpdateRatioUtils.partnerUserMapper = partnerUserMapper;
  39. UpdateRatioUtils.partnerPremiumDetailsMapper = partnerPremiumDetailsMapper;
  40. UpdateRatioUtils.partnerUserService = partnerUserService;
  41. UpdateRatioUtils.kickbackChangeService = kickbackChangeService;
  42. }
  43. @PostConstruct
  44. public void init() {
  45. }
  46. public void loginBefore(String userId){
  47. Map<Integer, PartnerUser> allByUserId = getAllByUserId(userId);
  48. allByUserId.forEach((key, value) -> {
  49. BigDecimal latest = calculateCommission(String.valueOf(key),value.getUserId(),allByUserId);
  50. initializeCommissionRatio(value, latest);
  51. });
  52. }
  53. private void initializeCommissionRatio(PartnerUser value, BigDecimal latest) {
  54. BigDecimal mostRecent = SpringUtil.getBean(PartnerKickbackChangeService.class).mostRecentRecord(value.getUserId(),String.valueOf(value.getGrade()));
  55. if (mostRecent == null){
  56. PartnerKickbackChange change = new PartnerKickbackChange();
  57. change.setUserId(value.getUserId());
  58. change.setUserGrade(String.valueOf(value.getGrade()));
  59. change.setOriginalCommission(latest);
  60. change.setAfterChange(null);
  61. change.setDeptId(value.getDeptId());
  62. change.setChangeTime(new Date());
  63. kickbackChangeService.saveKickbackChange(change);
  64. }
  65. }
  66. public void loginChange(String userId){
  67. Map<Integer, PartnerUser> allByUserId = getAllByUserId(userId);
  68. saveChange(allByUserId);
  69. }
  70. public Map<Integer, PartnerUser> getAllByUserId(String userId) {
  71. Map<Integer, PartnerUser> map = new HashMap<>();
  72. List<PartnerUser> userList = partnerUserMapper.queryByUserId(userId);
  73. if (CollectionUtil.isNotEmpty(userList)) {
  74. for (PartnerUser user : userList) {
  75. getMap(map, user);
  76. }
  77. }
  78. return map;
  79. }
  80. private static void saveChange(Map<Integer, PartnerUser> map) {
  81. List<PartnerKickbackChange> kickbackChange = new ArrayList<>();
  82. for (Map.Entry<Integer, PartnerUser> entry : map.entrySet()) {
  83. String key = String.valueOf(entry.getKey());
  84. PartnerUser value = entry.getValue();
  85. BigDecimal latest = calculateCommission(key,value.getUserId(),map);
  86. BigDecimal mostRecent = SpringUtil.getBean(PartnerKickbackChangeService.class).mostRecentRecord(value.getUserId(),key);
  87. getPartnerKickbackChange(latest, mostRecent, value, kickbackChange,map);
  88. }
  89. for (PartnerKickbackChange change : kickbackChange) {
  90. kickbackChangeService.saveKickbackChange(change);
  91. }
  92. }
  93. private static void getMap(Map<Integer, PartnerUser> map, PartnerUser user) {
  94. map.put(user.getGrade(), user);
  95. while (true) {
  96. Integer userGrade = user.getGrade();
  97. int i = userGrade - 1;
  98. if (0 == i) {
  99. break;
  100. }
  101. user = partnerUserMapper.queryUser(user.getReferrerId(),i );
  102. if (user == null) {
  103. break;
  104. }
  105. map.put(user.getGrade(),user);
  106. }
  107. }
  108. public void before(String referrerId, Integer grade){
  109. Map<Integer, PartnerUser> map = new HashMap<>();
  110. PartnerUser user = partnerUserMapper.queryUser(referrerId, grade);
  111. if (user != null) {
  112. getMap(map, user);
  113. }
  114. for (Map.Entry<Integer, PartnerUser> entry : map.entrySet()) {
  115. String key = String.valueOf(entry.getKey());
  116. PartnerUser value = entry.getValue();
  117. BigDecimal latest = calculateCommission(key,value.getUserId(),map);
  118. initializeCommissionRatio(value, latest);
  119. }
  120. }
  121. public void addChangeRecord(String userId){
  122. Map<Integer, PartnerUser> allByUserId = getAllByUserId(userId);
  123. saveChange(allByUserId);
  124. }
  125. public static void getPartnerKickbackChange(BigDecimal latest,BigDecimal mostRecent,PartnerUser details,List<PartnerKickbackChange> list,Map<Integer, PartnerUser> map){
  126. if (mostRecent == null){
  127. PartnerKickbackChange change = getChange(null, latest, details,map);
  128. list.add( change);
  129. }else {
  130. if (latest.compareTo(mostRecent) != 0){
  131. PartnerKickbackChange change = getChange(latest, mostRecent, details,map);
  132. list.add( change);
  133. }
  134. }
  135. }
  136. private static PartnerKickbackChange getChange(BigDecimal bigDecimal, BigDecimal mostRecent, PartnerUser details,Map<Integer, PartnerUser> map) {
  137. PartnerKickbackChange change = new PartnerKickbackChange();
  138. change.setUserId(details.getUserId());
  139. change.setUserGrade(String.valueOf(details.getGrade()));
  140. change.setOriginalCommission(mostRecent);
  141. change.setAfterChange(bigDecimal);
  142. String reason = getReason(String.valueOf(details.getGrade()), details.getUserId(),map);
  143. change.setChangeReason(reason);
  144. change.setDeptId(details.getDeptId());
  145. change.setChangeTime(new Date());
  146. return change;
  147. }
  148. public String getValue(Map<Integer, String> map, Integer grade) {
  149. if (map == null) {
  150. return "";
  151. }
  152. String value = map.get(grade);
  153. return value != null ? value : "";
  154. }
  155. public static BigDecimal calculateCommission(String grade, String userId,Map<Integer, PartnerUser> map) {
  156. CommissionRulesVo rulesVo = commissionService.queryAll();
  157. if (rulesVo == null) return BigDecimal.ZERO;
  158. BigDecimal gl = BigDecimal.ZERO;
  159. if (StringUtils.equals("1", grade)){
  160. gl = BigDecimal.ZERO;
  161. }
  162. if (StringUtils.equals("2", grade) || StringUtils.equals("3", grade)){
  163. gl = ladderCommission("gl" , grade,
  164. rulesVo.getAdministrator().getRulesRatioList(), userId, rulesVo.getAdministrator(),map);
  165. }
  166. BigDecimal hh = BigDecimal.ZERO;
  167. if (StringUtils.equals("3", grade) || StringUtils.equals("4", grade)){
  168. hh = ladderCommission(StringUtils.equals("3",grade) ? "levelGzs" :"gzs",grade, rulesVo.getPartner().getRulesRatioList(), userId, rulesVo.getPartner(),map);
  169. }
  170. if (StringUtils.equals("1", grade)) {
  171. return new BigDecimal(rulesVo.getOriginator());
  172. }
  173. if (StringUtils.equals("2", grade)) {
  174. PartnerCommissionRules administrator = rulesVo.getAdministrator();
  175. if (isZero(gl)){
  176. return new BigDecimal(administrator.getDefaultRatio());
  177. }else {
  178. return new BigDecimal(administrator.getSharedRatio()).subtract(gl);
  179. }
  180. }
  181. if (StringUtils.equals("3", grade)) {
  182. PartnerCommissionRules partner = rulesVo.getPartner();
  183. if (isZero(gl) && isZero(hh)) {
  184. return new BigDecimal(partner.getDefaultRatio())
  185. .add(subtractRatios(rulesVo.getAdministrator().getSharedRatio(), rulesVo.getAdministrator().getDefaultRatio()));
  186. } else if (isZero(hh) && !isZero(gl)) {
  187. return gl.add(new BigDecimal(partner.getDefaultRatio()));
  188. } else if (isZero(gl) && !isZero(hh)) {
  189. return new BigDecimal(partner.getSharedRatio()).subtract(hh)
  190. .add(subtractRatios(rulesVo.getAdministrator().getSharedRatio(), rulesVo.getAdministrator().getDefaultRatio()));
  191. }else{
  192. return gl.add(new BigDecimal(rulesVo.getPartner().getSharedRatio()).subtract(hh));
  193. }
  194. }
  195. if (StringUtils.equals("4", grade)) {
  196. return isZero(hh) ? subtractRatios(rulesVo.getPartner().getSharedRatio(), rulesVo.getPartner().getDefaultRatio()) : hh;
  197. }
  198. return BigDecimal.ZERO;
  199. }
  200. public static String getReason(String grade, String userId,Map<Integer, PartnerUser> map) {
  201. CommissionRulesVo rulesVo = commissionService.queryAll();
  202. if (rulesVo == null) return null;
  203. BigDecimal gl = BigDecimal.ZERO;
  204. if (StringUtils.equals("1", grade)){
  205. return "";
  206. }
  207. if (StringUtils.equals("2", grade) || StringUtils.equals("3", grade)){
  208. return obtainReason("gl" , grade,
  209. rulesVo.getAdministrator().getRulesRatioList(), userId, rulesVo.getAdministrator(),map);
  210. }
  211. BigDecimal hh = BigDecimal.ZERO;
  212. if (StringUtils.equals("3", grade) || StringUtils.equals("4", grade)){
  213. return obtainReason(StringUtils.equals("3",grade) ? "levelGzs" :"gzs",grade, rulesVo.getPartner().getRulesRatioList(), userId, rulesVo.getPartner(),map);
  214. }
  215. return null;
  216. }
  217. public static String obtainReason(String type, String grade, List<PartnerRulesRatio> rulesRatioList, String userId, PartnerCommissionRules rules,Map<Integer, PartnerUser> map) {
  218. CommissionValidityPeriod period = CalculateCommissionUtils.getCommissionValidityPeriod(rules, userId, grade);
  219. List<PartnerRulesRatio> sortedList = rulesRatioList.stream()
  220. .sorted(Comparator.comparing(PartnerRulesRatio::getKickback).reversed())
  221. .collect(Collectors.toList());
  222. BigDecimal sumPremium = BigDecimal.ZERO;
  223. Set<String> userIdList = new HashSet<>(0);
  224. if(StringUtils.equals("2",grade)){
  225. PartnerUser s = map.get(3);
  226. if (!Objects.isNull(s)){
  227. userIdList = CalculateCommissionUtils.getUserIdList(s.getUserId());
  228. }
  229. }
  230. if (StringUtils.equals("3",grade) ){
  231. PartnerUser s = map.get(4);
  232. if (!Objects.isNull(s)){
  233. userIdList = CalculateCommissionUtils.getUserIdList(s.getUserId());
  234. }
  235. }
  236. if (StringUtils.equals("4",grade)){
  237. PartnerUser s = map.get(4);
  238. if (!Objects.isNull(s)){
  239. userIdList = CalculateCommissionUtils.getUserIdList(s.getUserId());
  240. }
  241. }
  242. if (CollectionUtil.isNotEmpty(userIdList)){
  243. QueryWrapper<PartnerPremiumDetails> queryWrapper = new QueryWrapper<>();
  244. queryWrapper.in("user_id", userIdList);
  245. if (StringUtils.isNotEmpty(period.getStartDate()) && StringUtils.isNotEmpty(period.getEndDate())) {
  246. queryWrapper.between("create_time", period.getStartDate(), period.getEndDate());
  247. }
  248. BigDecimal totalSumPremium = partnerPremiumDetailsMapper.selectTotalSumPremium(queryWrapper);
  249. sumPremium = Optional.ofNullable(totalSumPremium).orElse(BigDecimal.ZERO);
  250. }
  251. Integer number = 0;
  252. switch (type) {
  253. case "gl":
  254. PartnerUser s = map.get(3);
  255. if (!Objects.isNull( s)){
  256. number = partnerUserMapper.selectNumber(s.getUserId(), "4", period);
  257. }
  258. break;
  259. case "levelGzs":
  260. PartnerUser s1 = map.get(4);
  261. if (!Objects.isNull( s1)){
  262. number = partnerUserMapper.selectNumber4(s1.getUserId(), "5", period);
  263. }
  264. break;
  265. case "gzs":
  266. number = partnerUserMapper.selectByUserIdNumber(userId, "5", period);
  267. break;
  268. default:
  269. return null;
  270. }
  271. BigDecimal numberBD = BigDecimal.valueOf(number);
  272. for (PartnerRulesRatio ratio : sortedList) {
  273. int allSatisfied = ratio.getAllSatisfied();
  274. List<PartnerRatio> ratioList = ratio.getPartnerRatioList();
  275. if (CollectionUtil.isEmpty(ratioList)) continue;
  276. BigDecimal min = ratioList.get(0).getMin();
  277. BigDecimal min1 = ratioList.get(1).getMin();
  278. boolean ry = ratioList.get(0).isRy();
  279. boolean bf = ratioList.get(1).isBf();
  280. if (ry && bf) {
  281. if (allSatisfied == 1) {
  282. if (numberBD.compareTo(min) >= 0 && sumPremium.compareTo(min1) >= 0) {
  283. return "邀请人达" + min + "人,累计保费达" + min1 + "元";
  284. }
  285. } else {
  286. if (numberBD.compareTo(min) >= 0) {
  287. return "邀请人达" + min + "人";
  288. }else if(sumPremium.compareTo(min1) >= 0){
  289. return "累计保费达" + min1 + "元";
  290. }
  291. }
  292. }else if (ry && !bf){
  293. if (allSatisfied != 1) {
  294. if (numberBD.compareTo(min) >= 0) {
  295. return "邀请人达" + min + "人";
  296. }
  297. }
  298. }else if (!ry && bf){
  299. if (allSatisfied != 1) {
  300. if (sumPremium.compareTo(min1) >= 0) {
  301. return "累计保费达" + min1 + "元";
  302. }
  303. }
  304. }
  305. }
  306. return null;
  307. }
  308. public static BigDecimal ladderCommission(String type, String grade, List<PartnerRulesRatio> rulesRatioList, String userId, PartnerCommissionRules rules,Map<Integer, PartnerUser> map) {
  309. CommissionValidityPeriod period = CalculateCommissionUtils.getCommissionValidityPeriod(rules, userId, grade);
  310. List<PartnerRulesRatio> sortedList = rulesRatioList.stream()
  311. .sorted(Comparator.comparing(PartnerRulesRatio::getKickback).reversed())
  312. .collect(Collectors.toList());
  313. BigDecimal sumPremium = BigDecimal.ZERO;
  314. Set<String> userIdList = new HashSet<>(0);
  315. if (StringUtils.equals("2",grade)){
  316. PartnerUser s = map.get(3);
  317. if (!Objects.isNull(s)){
  318. userIdList = CalculateCommissionUtils.getUserIdList(s.getUserId());
  319. }
  320. }
  321. if (StringUtils.equals("3",grade)){
  322. PartnerUser s = map.get(4);
  323. if (!Objects.isNull(s)){
  324. userIdList = CalculateCommissionUtils.getUserIdList(s.getUserId());
  325. }
  326. }
  327. if (StringUtils.equals("4",grade)){
  328. PartnerUser s = map.get(4);
  329. if (!Objects.isNull(s)){
  330. userIdList = CalculateCommissionUtils.getUserIdList(s.getUserId());
  331. }
  332. }
  333. if (CollectionUtil.isNotEmpty(userIdList)){
  334. QueryWrapper<PartnerPremiumDetails> queryWrapper = new QueryWrapper<>();
  335. queryWrapper.in("user_id", userIdList);
  336. if (StringUtils.isNotEmpty(period.getStartDate()) && StringUtils.isNotEmpty(period.getEndDate())) {
  337. queryWrapper.between("create_time", period.getStartDate(), period.getEndDate());
  338. }
  339. BigDecimal totalSumPremium = partnerPremiumDetailsMapper.selectTotalSumPremium(queryWrapper);
  340. sumPremium = Optional.ofNullable(totalSumPremium).orElse(BigDecimal.ZERO);
  341. }
  342. Integer number = 0;
  343. switch (type) {
  344. case "gl":
  345. PartnerUser s = map.get(3);
  346. if (!Objects.isNull( s)){
  347. number = partnerUserMapper.selectNumber(s.getUserId(), "4", period);
  348. }
  349. break;
  350. case "levelGzs":
  351. PartnerUser s1 = map.get(4);
  352. if (!Objects.isNull( s1)){
  353. number = partnerUserMapper.selectNumber4(s1.getUserId(), "5", period);
  354. }
  355. break;
  356. case "gzs":
  357. number = partnerUserMapper.selectByUserIdNumber(userId, "5", period);
  358. break;
  359. default:
  360. return BigDecimal.ZERO;
  361. }
  362. BigDecimal numberBD = BigDecimal.valueOf(number);
  363. for (PartnerRulesRatio ratio : sortedList) {
  364. int allSatisfied = ratio.getAllSatisfied();
  365. List<PartnerRatio> ratioList = ratio.getPartnerRatioList();
  366. if (CollectionUtil.isEmpty(ratioList)) continue;
  367. BigDecimal min = ratioList.get(0).getMin();
  368. BigDecimal min1 = ratioList.get(1).getMin();
  369. boolean ry = ratioList.get(0).isRy();
  370. boolean bf = ratioList.get(1).isBf();
  371. if (ry && bf) {
  372. if (allSatisfied == 1) {
  373. if (numberBD.compareTo(min) >= 0 && sumPremium.compareTo(min1) >= 0) {
  374. return ratio.getKickback();
  375. }
  376. } else {
  377. if (numberBD.compareTo(min) >= 0 || sumPremium.compareTo(min1) >= 0) {
  378. return ratio.getKickback();
  379. }
  380. }
  381. }else if (ry && !bf){
  382. if (allSatisfied != 1) {
  383. if (numberBD.compareTo(min) >= 0) {
  384. return ratio.getKickback();
  385. }
  386. }
  387. }else if (!ry && bf){
  388. if (allSatisfied != 1) {
  389. if (sumPremium.compareTo(min1) >= 0) {
  390. return ratio.getKickback();
  391. }
  392. }
  393. }
  394. }
  395. return BigDecimal.ZERO;
  396. }
  397. private static boolean isZero(BigDecimal value) {
  398. return value.compareTo(BigDecimal.ZERO) == 0;
  399. }
  400. private static BigDecimal subtractRatios(String a, String b) {
  401. return new BigDecimal(a).subtract(new BigDecimal(b));
  402. }
  403. }