|
|
package com.yohoufo.order.utils;
|
|
|
|
|
|
import com.yohoufo.dal.order.model.InviteSettlementItem;
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
...
|
...
|
@@ -11,6 +12,7 @@ import java.time.ZoneOffset; |
|
|
import java.util.List;
|
|
|
import java.util.Objects;
|
|
|
import java.util.function.BiPredicate;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* @author LUOXC
|
...
|
...
|
@@ -58,27 +60,48 @@ public class InviteSettlementUtils { |
|
|
* @param items 待结算订单
|
|
|
* @return
|
|
|
*/
|
|
|
public static BigDecimal calculateSettleAmountOfType2(LocalDateTime inviteTime, List<InviteSettlementItem> items) {
|
|
|
public static Pair<BigDecimal, List<InviteSettlementItem>> calculateSettleAmountOfType2(LocalDateTime inviteTime, LocalDateTime settleTime, List<InviteSettlementItem> items) {
|
|
|
// 被邀请当月月初开始计算
|
|
|
LocalDateTime calculateInviteTime = LocalDateTime.of(LocalDate.of(inviteTime.getYear(), inviteTime.getMonth(), 1), LocalTime.MIN);
|
|
|
// 一个月内
|
|
|
LocalDateTime calculateStartTime = LocalDateTime.of(LocalDate.of(inviteTime.getYear(), inviteTime.getMonth(), 1), LocalTime.MIN);
|
|
|
|
|
|
LocalDateTime afterOneMonth = calculateStartTime.plusMonths(1);
|
|
|
|
|
|
LocalDateTime afterFiveMonth = calculateStartTime.plusMonths(5);
|
|
|
|
|
|
// 被邀请来年元旦
|
|
|
LocalDateTime calculateFinnalEndTime = LocalDateTime.of(LocalDate.of(inviteTime.getYear() + 1, 1, 1), LocalTime.MIN);
|
|
|
|
|
|
BiPredicate<InviteSettlementItem, LocalDateTime> iaAfterOrEqual = (item, month) -> {
|
|
|
LocalDateTime createTime = newLocalDateTimeOfEpochSecond(item.getCreateTime());
|
|
|
return createTime.isAfter(month) || createTime.isEqual(month);
|
|
|
};
|
|
|
|
|
|
// 一个月内无需结算
|
|
|
if (settleTime.isBefore(afterOneMonth)) {
|
|
|
return Pair.of(BigDecimal.ZERO, items);
|
|
|
}
|
|
|
|
|
|
|
|
|
// 一个月内结算金额
|
|
|
BigDecimal inOneMonthTotalSettleAmount = items.stream()
|
|
|
.filter(item -> newLocalDateTimeOfEpochSecond(item.getOrderCreateTime()).isBefore(calculateInviteTime.plusMonths(1)))
|
|
|
.filter(item -> newLocalDateTimeOfEpochSecond(item.getCreateTime()).isBefore(afterOneMonth))
|
|
|
.map(InviteSettlementItem::getOrderAmount)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add)
|
|
|
.multiply(BigDecimal.valueOf(0.02));
|
|
|
|
|
|
BiPredicate<InviteSettlementItem, Integer> iaAfterOrEqual = (item, months) -> {
|
|
|
LocalDateTime orderCreateTime = newLocalDateTimeOfEpochSecond(item.getOrderCreateTime());
|
|
|
LocalDateTime afterInviteMonth = calculateInviteTime.plusMonths(months);
|
|
|
return orderCreateTime.isAfter(afterInviteMonth) || orderCreateTime.isEqual(afterInviteMonth);
|
|
|
};
|
|
|
// 五个月内只结算1个月内的订单
|
|
|
if (settleTime.isBefore(afterFiveMonth)) {
|
|
|
return Pair.of(
|
|
|
inOneMonthTotalSettleAmount,
|
|
|
items.stream().filter(item -> iaAfterOrEqual.test(item, afterOneMonth)).collect(Collectors.toList())
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// 五个月内
|
|
|
// 五个月内结算金额
|
|
|
BigDecimal inFiveMonthTotalSettleAmount;
|
|
|
BigDecimal inFiveMonthTotalOrderAmount = items.stream()
|
|
|
.filter(item -> iaAfterOrEqual.test(item, 1))
|
|
|
.filter(item -> newLocalDateTimeOfEpochSecond(item.getOrderCreateTime()).isBefore(calculateInviteTime.plusMonths(5)))
|
|
|
.filter(item -> iaAfterOrEqual.test(item, afterOneMonth))
|
|
|
.filter(item -> newLocalDateTimeOfEpochSecond(item.getCreateTime()).isBefore(calculateFinnalEndTime.isBefore(afterFiveMonth) ? calculateFinnalEndTime : afterFiveMonth))
|
|
|
.map(InviteSettlementItem::getOrderAmount)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
if (inFiveMonthTotalOrderAmount.compareTo(BigDecimal.valueOf(100_0000)) < 0) {
|
...
|
...
|
@@ -91,10 +114,19 @@ public class InviteSettlementUtils { |
|
|
inFiveMonthTotalSettleAmount = inFiveMonthTotalOrderAmount.multiply(BigDecimal.valueOf(0.020));
|
|
|
}
|
|
|
|
|
|
// 五个月以后
|
|
|
// 五个月以后,1年内只结算五个月内的订单
|
|
|
if (settleTime.isBefore(afterFiveMonth)) {
|
|
|
return Pair.of(
|
|
|
inOneMonthTotalSettleAmount.add(inFiveMonthTotalSettleAmount),
|
|
|
items.stream().filter(item -> iaAfterOrEqual.test(item, calculateFinnalEndTime.isBefore(afterFiveMonth) ? calculateFinnalEndTime : afterFiveMonth)).collect(Collectors.toList())
|
|
|
);
|
|
|
}
|
|
|
|
|
|
// 五个月以后结算金额
|
|
|
BigDecimal outFiveMonthTotalSettleAmount;
|
|
|
BigDecimal outFiveMonthTotalOrderAmount = items.stream()
|
|
|
.filter(item -> iaAfterOrEqual.test(item, 5))
|
|
|
.filter(item -> iaAfterOrEqual.test(item, afterFiveMonth))
|
|
|
.filter(item -> newLocalDateTimeOfEpochSecond(item.getCreateTime()).isBefore(calculateFinnalEndTime))
|
|
|
.map(InviteSettlementItem::getOrderAmount)
|
|
|
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
|
|
if (outFiveMonthTotalOrderAmount.compareTo(BigDecimal.valueOf(180_0000)) < 0) {
|
...
|
...
|
@@ -107,7 +139,10 @@ public class InviteSettlementUtils { |
|
|
outFiveMonthTotalSettleAmount = outFiveMonthTotalOrderAmount.multiply(BigDecimal.valueOf(0.018));
|
|
|
}
|
|
|
|
|
|
return inOneMonthTotalSettleAmount.add(inFiveMonthTotalSettleAmount).add(outFiveMonthTotalSettleAmount);
|
|
|
return Pair.of(
|
|
|
inOneMonthTotalSettleAmount.add(inFiveMonthTotalSettleAmount).add(outFiveMonthTotalSettleAmount),
|
|
|
items.stream().filter(item -> iaAfterOrEqual.test(item, calculateFinnalEndTime)).collect(Collectors.toList())
|
|
|
);
|
|
|
}
|
|
|
|
|
|
public static ZoneOffset zoneOffset() {
|
...
|
...
|
|