Files
jsowell-charger-web/TestCalculateBalanceRefund.java
2025-12-16 16:55:39 +08:00

122 lines
6.4 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
public class TestCalculateBalanceRefund {
/**
* 计算余额退款(包含电费和保险费)
* <p>
* 业务规则:
* 1. 总支付金额 = principalPay + giftPay
* 2. 电费预付款 = 总支付金额 - insuranceAmount
* 3. 实际电费消费金额 = orderAmount - discountAmount
* 4. 支付时优先使用本金,消费时也优先扣除本金
* 5. 保险费优先从本金中扣除
* 6. 电费实际消费金额 > 1 时,保险费不退;否则需要退保险费
*
* @param principalPay 本金支付金额
* @param giftPay 赠金支付金额
* @param orderAmount 消费金额
* @param discountAmount 折扣金额
* @param insuranceAmount 保险费金额
* @return Map包含returnPrincipal本金退款for电费returnGift赠金退款for电费
* returnPrincipalForInsurance本金退款for保险费returnGiftForInsurance赠金退款for保险费
*/
protected static Map<String, BigDecimal> calculateBalanceRefund(BigDecimal principalPay, BigDecimal giftPay,
BigDecimal orderAmount, BigDecimal discountAmount,
BigDecimal insuranceAmount) {
Map<String, BigDecimal> resultMap = new HashMap<>();
// 参数校验null值处理为0
principalPay = principalPay == null ? BigDecimal.ZERO : principalPay;
giftPay = giftPay == null ? BigDecimal.ZERO : giftPay;
orderAmount = orderAmount == null ? BigDecimal.ZERO : orderAmount;
discountAmount = discountAmount == null ? BigDecimal.ZERO : discountAmount;
insuranceAmount = insuranceAmount == null ? BigDecimal.ZERO : insuranceAmount;
// 总支付金额
BigDecimal totalPay = principalPay.add(giftPay);
// 电费预付款 = 总支付金额 - 保险费
BigDecimal electricityPrepayment = totalPay.subtract(insuranceAmount);
// 实际电费消费金额 = 消费金额 - 折扣金额
BigDecimal actualElectricityConsumption = orderAmount.subtract(discountAmount);
if (actualElectricityConsumption.compareTo(BigDecimal.ZERO) < 0) {
actualElectricityConsumption = BigDecimal.ZERO;
}
// 支付时优先用本金,保险费全部从本金中扣除
// 本金用于保险费的部分(优先从本金扣除保险费)
BigDecimal principalForInsurance = principalPay.min(insuranceAmount);
// 赠金用于保险费的部分(如果本金不够支付保险费,从赠金中扣除)
BigDecimal giftForInsurance = insuranceAmount.subtract(principalForInsurance);
if (giftForInsurance.compareTo(BigDecimal.ZERO) < 0) {
giftForInsurance = BigDecimal.ZERO;
}
// 本金用于电费的部分 = 总本金 - 本金用于保险费的部分
BigDecimal principalForElectricity = principalPay.subtract(principalForInsurance);
// 赠金用于电费的部分 = 总赠金 - 赠金用于保险费的部分
BigDecimal giftForElectricity = giftPay.subtract(giftForInsurance);
// 计算电费退款(消费时优先扣除本金)
BigDecimal principalConsumed = principalForElectricity.min(actualElectricityConsumption);
BigDecimal giftConsumed = actualElectricityConsumption.subtract(principalConsumed);
if (giftConsumed.compareTo(BigDecimal.ZERO) < 0) {
giftConsumed = BigDecimal.ZERO;
}
// 电费退款
BigDecimal returnPrincipal = principalForElectricity.subtract(principalConsumed);
BigDecimal returnGift = giftForElectricity.subtract(giftConsumed);
if (returnPrincipal.compareTo(BigDecimal.ZERO) < 0) {
returnPrincipal = BigDecimal.ZERO;
}
if (returnGift.compareTo(BigDecimal.ZERO) < 0) {
returnGift = BigDecimal.ZERO;
}
// 计算保险费退款:电费实际消费金额 > 1 时,保险费不退;否则需要退保险费
BigDecimal returnPrincipalForInsurance = BigDecimal.ZERO;
BigDecimal returnGiftForInsurance = BigDecimal.ZERO;
if (actualElectricityConsumption.compareTo(BigDecimal.ONE) <= 0) {
// 需要退保险费
returnPrincipalForInsurance = principalForInsurance;
returnGiftForInsurance = giftForInsurance;
}
resultMap.put("returnPrincipal", returnPrincipal);
resultMap.put("returnGift", returnGift);
resultMap.put("returnPrincipalForInsurance", returnPrincipalForInsurance);
resultMap.put("returnGiftForInsurance", returnGiftForInsurance);
System.out.println("计算余额退款: 本金支付=" + principalPay + ", 赠金支付=" + giftPay +
", 消费金额=" + orderAmount + ", 折扣金额=" + discountAmount +
", 保险费=" + insuranceAmount + ", 实际电费消费=" + actualElectricityConsumption +
", 电费退款(本金=" + returnPrincipal + ", 赠金=" + returnGift +
"), 保险费退款(本金=" + returnPrincipalForInsurance + ", 赠金=" + returnGiftForInsurance + ")");
return resultMap;
}
public static void main(String[] args) {
System.out.println("测试用例1: 本金30.5, 赠金20, 消费10, 折扣0, 保险费0.5");
BigDecimal principalPay = new BigDecimal("30.5");
BigDecimal giftPay = new BigDecimal("20");
BigDecimal orderAmount = new BigDecimal("10");
BigDecimal discountAmount = new BigDecimal("0");
BigDecimal insuranceAmount = new BigDecimal("0.5");
Map<String, BigDecimal> result = calculateBalanceRefund(principalPay, giftPay, orderAmount, discountAmount, insuranceAmount);
System.out.println("结果: " + result);
System.out.println();
System.out.println("期望结果: 电费退款(本金=20.5, 赠金=19.5), 保险费退款(本金=0, 赠金=0)");
System.out.println("实际结果: 电费退款(本金=" + result.get("returnPrincipal") +
", 赠金=" + result.get("returnGift") +
"), 保险费退款(本金=" + result.get("returnPrincipalForInsurance") +
", 赠金=" + result.get("returnGiftForInsurance") + ")");
}
}