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; } }