放款(提现、⽤信)-试算还款计划-JAVA实现
1、等额本⾦:每期本⾦相同
2、等额本息:每期还款额相同
/**
* @author wzh
* @date 2019-11-20 18:45
* @description 试算还款计划-⼊参
*/
@Data
@Builder
public class CalculateRepayPlanReq implements Serializable {
/
**
* 借款⾦额(元),⾮空
*/
private BigDecimal principle;
/**
* 期限天,⾮空
*/
private Integer termDay;
/**
* 年利率,⽐如⼀年期贷款4.35,传⼊4.35,⾮空
*/
private BigDecimal yearRate;
/**
* 起息⽇,⾮空
*/
private Date beginProfitDate;
/**
* 费率集合,可空
*/
private List<FeeRuleReq> feeRulePojoList;
/**
* 特殊⽇期范围,例如:28-31
*/
private String specialDateRange;
/**
* 特殊⽇期调整⽇,27
*/
private String specialDateAdjustDay;
}
/**
* @Author: wzh
* @Date: 2019-03-28T15:33:47.526
* @Description: 还款计划
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RepayPlanRes implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 总期次
*/
@NotNull
private Integer repayNum;
private Integer repayNum;
/**
* 当前期次
*/
@NotNull
private Integer currentNum;
/**
* 开始时间
*/
@NotNull
private Date startDate;
/**
* 到期时间
*/
@NotNull
private Date endDate;
/**
* 收益天数
*/
@NotNull
private Integer profitDays;
/
**
* 应还时间
*/
@NotNull
private Date preRepayDate;
/**
* 应还总额
*/
@NotNull
private BigDecimal preRepayAmt;
/**
* 应还本⾦
*/
@NotNull
private BigDecimal preRepayPrincipal;
/**
* 应还利息
*/
@NotNull
private BigDecimal preRepayInterest;
/**
* 应还⼿续费
*/
@NotNull
private BigDecimal preRepayFee;
/**
* 应还账户管理费
*/
@NotNull
private BigDecimal preRepayManagementFee;    /**
* 剩余本⾦
*/
@NotNull
private BigDecimal leftPrincipal;
private BigDecimal leftPrincipal;bigdecimal转换为integer
}
/**
* 包装公共⽅法
*
* @author wzh
* @date 2019年09⽉23⽇11:27:04
*/
public abstract class AbstractCalculateServiceImpl implements CalculateService {
/**
* 期限天转期限⽉
* 备注:主要适⽤于按⽉计息的
* @param termDay
* @return
*/
protected Integer transTermMonth(Integer termDay) {
//按⽉计算,除以30取整
BigDecimal termDayBg=new BigDecimal(termDay);
return termDayBg.divide(new BigDecimal(30),0,BigDecimal.ROUND_HALF_UP).intValue();
}
/**
* ⽉利率
* 备注:主要适⽤于按⽉计息的
* @param yearRate
* @return
*/
protected BigDecimal transMonthRate(BigDecimal yearRate) {
//⽉利率
return yearRate.divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(0.01));    }
/**
* 返回⽇利率
*
* @param yearRate
* @return
*/
protected BigDecimal transDayRate(BigDecimal yearRate) {
return yearRate.divide(new BigDecimal(360),6,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(0.01));    }
/**
* 计算⼿续费
* @param principle    本⾦
* @param feeRulePojoList      费率规则
* @return
*/
protected BigDecimal calculateFee(BigDecimal principle,List<FeeRuleReq> feeRulePojoList) {
if(CollectionUtils.isEmpty(feeRulePojoList)){
return BigDecimal.ZERO;
}
BigDecimal feeTotal = BigDecimal.ZERO;
for(FeeRuleReq feeRulePojo:feeRulePojoList) {
BigDecimal fee = BigDecimal.ZERO;
EnumFeeType enumFeeType = FeeType();
if (ONCE_SERVICE_FEE.equals(enumFeeType)) {
fee = principle.FeeRate()).multiply(new BigDecimal(0.01));
} else if (FEE.equals(enumFeeType)) {
fee = principle.FeeRate()).multiply(new BigDecimal(0.01));
}
feeTotal=feeTotal.add(fee);
}
return feeTotal;
}
/**
* 计算账户管理费
* @param principle    本⾦
* @param leftPrinciple 剩余本⾦
* @param feeRulePojoList      费率规则
* @return
*/
protected BigDecimal calculateManagementFee(BigDecimal principle, BigDecimal leftPrinciple, List<FeeRuleReq> feeRulePojoList) {
if(CollectionUtils.isEmpty(feeRulePojoList)){
return BigDecimal.ZERO;
}
BigDecimal feeTotal = BigDecimal.ZERO;
for(FeeRuleReq feeRulePojo:feeRulePojoList) {
BigDecimal fee = BigDecimal.ZERO;
EnumFeeType enumFeeType = FeeType();
if (MANAGEMENT_FEE.equals(enumFeeType)) {
if (FeeCalculateType() == EnumFeeCalculateType.LOANAMT_FEERATE) {
fee = principle.FeeRate()).multiply(new BigDecimal(0.01));
} else if (FeeCalculateType() == EnumFeeCalculateType.LEFTPRINCIPLE_FEERATE) {
fee = leftPrinciple.FeeRate()).multiply(new BigDecimal(0.01));
}
}
feeTotal=feeTotal.add(fee);
}
return feeTotal;
}
}
/**
* 等额本息
*
* @author wzh
* @date 2019年09⽉19⽇16:17:12
*/
@Slf4j
@Component
public class EqualAmtInterestCalculate extends AbstractCalculateServiceImpl {
@Override
public List<RepayPlanRes> calculateRepayPlan(CalculateRepayPlanReq calculateRepayPlanDto) {
BigDecimal Principle();
Date BeginProfitDate();
List<RepayPlanRes> repayPlanList=new ArrayList<RepayPlanRes>();
//转期限⽉
Integer termMonth=TermDay());
//⽉利率
BigDecimal monthRate=YearRate());
BigDecimal monthRate=YearRate());
/**
* 计算每期应还息费总额=(贷款本⾦×期利率×(1+期利率)^还款期数)÷((1+期利率)^还款期数-1) (四舍五⼊)
*/
BigDecimal periodAmt = principle.multiply(monthRate).multiply((BigDecimal.ONE.add(monthRate)).pow(termMonth))
.divide(((BigDecimal.ONE.add(monthRate)).pow(termMonth)).subtract(BigDecimal.ONE), 2,BigDecimal.ROUND_HALF_UP);
//应还总利息
//BigDecimal preRepayInterestTotal=principle.multiply(BigDecimal.valueOf(repayNum+1)).multiply(monthRate).divide(new BigDecimal(2));
//剩余本⾦
BigDecimal leftPrincipal=principle;
for(int i=1;i<=termMonth;i++) {
RepayPlanRes repayPlanPojo = new RepayPlanRes();
//总期次
repayPlanPojo.setRepayNum(termMonth);
//当期期次
repayPlanPojo.setCurrentNum(i);
if(i==1){
//起息⽇
repayPlanPojo.setStartDate(date);
}else{
Date startDate=DateUtil.dateAddMonth(date,i-1);
if(!CollectionUtils.isEmpty(dayList)&&ains(DateUtil.formateDate(startDate,DateUtil.FMT_DD))){
//处于范围期,下移⼀个⽉,再取⽉初X号
Date nextMonthDate=DateUtil.dateAddMonth(startDate,1);
repayPlanPojo.MonthBegin(nextMonthDate, Integer.SpecialDateAdjustDay())));                }else{
//起息⽇
repayPlanPojo.setStartDate(startDate);
}
}
Date endDate=DateUtil.dateAddMonth(date,i);
if(!CollectionUtils.isEmpty(dayList)&&ains(DateUtil.formateDate(endDate,DateUtil.FMT_DD))){
//处于范围期,下移⼀个⽉,再取⽉初X号
Date nextMonthDate=DateUtil.dateAddMonth(endDate,1);
repayPlanPojo.MonthBegin(nextMonthDate, Integer.parseInt(calculateRepa
//应还⽇
repayPlanPojo.MonthBegin(nextMonthDate, Integer.SpecialDateAdjustDay())));
}else{
//起息⽇
repayPlanPojo.setEndDate(endDate);
//应还⽇
repayPlanPojo.setPreRepayDate(endDate);
}
//收益天数
int StartDate(),EndDate());
//应还利息
BigDecimal preRepayInterest=leftPrincipal.multiply(monthRate);
//应还利息赋值
repayPlanPojo.setPreRepayInterest(preRepayInterest.setScale(2,BigDecimal.ROUND_HALF_UP));
//应还本⾦
BigDecimal preRepayPrinciple=periodAmt.subtract(preRepayInterest).setScale(2,BigDecimal.ROUND_HALF_UP);
//应还本⾦,判断是否最后⼀期
if(i==termMonth){
//最后⼀期应还本⾦
repayPlanPojo.setPreRepayPrincipal(leftPrincipal.setScale(2,BigDecimal.ROUND_HALF_UP));
//应还利息赋值
repayPlanPojo.setPreRepayInterest(periodAmt.subtract(leftPrincipal).setScale(2,BigDecimal.ROUND_HALF_UP));
}else{
//应还本⾦赋值

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。