puzhibing
昨天 63b68c39653208a1756640034c028789946d0e12
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.ruoyi.order.service.impl;
 
import com.ruoyi.other.api.domain.TCoupon;
 
import java.math.BigDecimal;
import java.math.RoundingMode;
 
public final class ChargingCouponSupport {
    private static final BigDecimal TEN = new BigDecimal("10");
    private static final int WHITELIST_BENEFIT_ALL_FREE = 1;
    private static final int WHITELIST_BENEFIT_ELECTRIC_FREE = 2;
    private static final int WHITELIST_BENEFIT_SERVICE_FREE = 3;
 
    private ChargingCouponSupport() {
    }
 
    static BigDecimal calculatePrepaymentAmount(BigDecimal rechargeAmount, boolean whitelistAllFree) {
        if (whitelistAllFree) {
            return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP);
        }
        return money(rechargeAmount).setScale(2, RoundingMode.HALF_UP);
    }
 
    /**
     * 兼容曾在预付阶段直接减掉优惠券金额的在途订单,退款基数不能超过真实收款。
     */
    static BigDecimal resolveSettlementPrepayment(BigDecimal rechargeAmount,
                                                  BigDecimal balancePayAmount,
                                                  BigDecimal thirdPayAmount,
                                                  BigDecimal upfrontCouponDiscount) {
        BigDecimal recharge = money(rechargeAmount);
        BigDecimal collected = money(balancePayAmount).add(money(thirdPayAmount));
        if (money(upfrontCouponDiscount).compareTo(BigDecimal.ZERO) > 0
                && collected.compareTo(BigDecimal.ZERO) > 0
                && collected.compareTo(recharge) < 0) {
            return collected;
        }
        return recharge;
    }
 
    /**
     * 优惠券只在充电结束时结算,且优惠金额不能超过剩余服务费。
     */
    static BigDecimal calculateSettlementDiscount(TCoupon coupon,
                                                   BigDecimal actualAmountBeforeCoupon,
                                                   BigDecimal remainingServiceCharge) {
        BigDecimal actualAmount = money(actualAmountBeforeCoupon);
        BigDecimal serviceCharge = money(remainingServiceCharge);
        if (coupon == null || actualAmount.compareTo(BigDecimal.ZERO) <= 0
                || serviceCharge.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO.setScale(4, RoundingMode.HALF_EVEN);
        }
        BigDecimal threshold = money(coupon.getMeetTheConditions());
        if (actualAmount.compareTo(threshold) < 0) {
            return BigDecimal.ZERO.setScale(4, RoundingMode.HALF_EVEN);
        }
 
        BigDecimal discount = BigDecimal.ZERO;
        if (Integer.valueOf(1).equals(coupon.getPreferentialMode())) {
            discount = money(coupon.getDiscountAmount());
        } else if (Integer.valueOf(2).equals(coupon.getPreferentialMode()) && coupon.getDiscount() != null) {
            discount = actualAmount.multiply(TEN.subtract(coupon.getDiscount())).divide(TEN);
            if (coupon.getMaximumDiscountAmount() != null) {
                discount = discount.min(coupon.getMaximumDiscountAmount());
            }
        }
        return discount.max(BigDecimal.ZERO).min(serviceCharge).setScale(4, RoundingMode.HALF_EVEN);
    }
 
    public static BigDecimal[] calculateWhitelistRefundSplitByBenefitType(boolean whitelistOrder,
                                                                          Integer whitelistBenefitType,
                                                             BigDecimal electrovalence,
                                                             BigDecimal serviceCharge) {
        BigDecimal electricDiscount = BigDecimal.ZERO;
        BigDecimal serviceDiscount = BigDecimal.ZERO;
        if (!whitelistOrder) {
            return new BigDecimal[]{electricDiscount, serviceDiscount};
        }
        if (Integer.valueOf(WHITELIST_BENEFIT_ALL_FREE).equals(whitelistBenefitType)) {
            electricDiscount = money(electrovalence);
            serviceDiscount = money(serviceCharge);
        } else if (Integer.valueOf(WHITELIST_BENEFIT_ELECTRIC_FREE).equals(whitelistBenefitType)) {
            electricDiscount = money(electrovalence);
        } else if (Integer.valueOf(WHITELIST_BENEFIT_SERVICE_FREE).equals(whitelistBenefitType)) {
            serviceDiscount = money(serviceCharge);
        }
        return new BigDecimal[]{electricDiscount, serviceDiscount};
    }
 
    private static BigDecimal money(BigDecimal value) {
        return value == null ? BigDecimal.ZERO : value;
    }
}