/**
* 计算两个日期之间的天数
* @param smdate -起始日期
* @param bdate -截至日期
* @return
* @throws ParseException
*/
public static Integer daysBetween(String smdate,String bdate) throws ParseException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(sdf.parse(smdate));
long time1 = cal.getTimeInMillis();
cal.setTime(sdf.parse(bdate));
long time2 = cal.getTimeInMillis();
long between_days=(time2-time1)/(1000*3600*24);
return Integer.parseInt(String.valueOf(between_days));
}
/**
* 按提款信息生成还本计划
* 暂时只有一次还本
* @return
*/
public static FinancTransWrRepayRo getRepayDetail(FinancTransWrListBo bo ) throws ParseException {
String pch = bo.getWithdrawalPc();//批次号
String startTime = bo.getWithdrawalStartDate();//提款开始日
String endTime = bo.getWithdrawalEndDate();//提款到期日
BigDecimal hkAmount = bo.getWithdrawalAmount();
FinancTransWrRepayRo repayRo = new FinancTransWrRepayRo();
repayRo.setWithdrawalPc( pch);
repayRo.setPlanRepayDate( endTime );
repayRo.setStartDate( startTime);
repayRo.setEndDate( endTime);
repayRo.setDays( daysBetween(startTime,endTime));
repayRo.setAddFlag("1");
repayRo.setRepayAmount( hkAmount);
return repayRo;
}
/**
* 获取还本列表
* @param result
* @param pchList
* @return
*/
public static void getRepayList( WithdrawalInfoRo result , List<FinancTransWrListBo> pchList ) throws ParseException {
List<FinancTransWrRepayRo> repayRos = result.getTransWrRepays();
if( repayRos ==null ){
repayRos = new ArrayList<>();
}
for( FinancTransWrListBo bo : pchList){
boolean b = true;
while ( b ) {
FinancTransWrRepayRo ro = getRepayDetail(bo);
if( ro ==null ){
break;
}
b = DateUtils.stringToDate(bo.getWithdrawalEndDate(),"yyyy-MM-dd").getTime() > DateUtils.stringToDate(ro.getEndDate(),"yyyy-MM-dd").getTime();
repayRos.add(ro);
}
}
result.setTransWrRepays( repayRos);
}
/**
* 付息
* @param startTime-本期开始时间
* @param phase ---支付第几期
* @param transWrInfoBo-提款主信息
* @param bo-提款批次信息
* @return
* @throws ParseException
*/
public static FinancTransWrInterpayRo getInterpayDetail( String startTime, int phase,FinancTransWrInfoBo transWrInfoBo , FinancTransWrListBo bo ) throws ParseException {
FinancTransWrInterpayRo interpayRo = new FinancTransWrInterpayRo();
BigDecimal hkAmount = bo.getWithdrawalAmount();//本金
BigDecimal ll= transWrInfoBo.getActRate().divide(new BigDecimal(100)); //利率
int jxfs= Integer.parseInt(transWrInfoBo.getRateMethod().split("/")[1]); //计息天数是360,365
//需要重新修改结束时间
String endTime = bo.getWithdrawalEndDate(); //按规则生成时间与end取最小值
String type = transWrInfoBo.getRatePayFreq();
if( "PAM".equals( type)){
//到期日支付
endTime = bo.getWithdrawalEndDate();
}else if("M".equals(type) ){
//按月支付
String endTmp = getNextMonthDate( bo.getWithdrawalStartDate(), phase);
if( DateUtils.stringToDate(endTime,"yyyy-MM-dd").getTime() > DateUtils.stringToDate(endTmp,"yyyy-MM-dd").getTime() ){
endTime = endTmp;
}
}else if( "MTHLY10".equals( type)) {
// 每月10日
String startTmp = bo.getWithdrawalStartDate();
startTmp =startTmp.substring(0, startTmp.lastIndexOf("-"))+"-10";
String endTmp = getNextMonthDate(startTmp, phase);
if( DateUtils.stringToDate(endTime,"yyyy-MM-dd").getTime() > DateUtils.stringToDate(endTmp,"yyyy-MM-dd").getTime() ){
endTime = endTmp;
}
}else if( "MTHLY21".equals(type)){
//MTHLY21 每月21日
String startTmp = bo.getWithdrawalStartDate();
startTmp =startTmp.substring(0, startTmp.lastIndexOf("-"))+"-21";
String endTmp = getNextMonthDate(startTmp, phase);
if( DateUtils.stringToDate(endTime,"yyyy-MM-dd").getTime() > DateUtils.stringToDate(endTmp,"yyyy-MM-dd").getTime() ){
endTime = endTmp;
}
}else if("Q21".equals(type)){
//Q21 每季末月21日
String startTmp = bo.getWithdrawalStartDate();
startTmp =startTmp.substring(0, startTmp.lastIndexOf("-"))+"-21";
String endTmp = getNextQuarter(startTmp, phase);
if( DateUtils.stringToDate(endTime,"yyyy-MM-dd").getTime() > DateUtils.stringToDate(endTmp,"yyyy-MM-dd").getTime() ){
endTime = endTmp;
}
}else if( "A".equals( type)){
//每年
String endTmp = getNextMonthDate( bo.getWithdrawalStartDate(), phase*12);
if( DateUtils.stringToDate(endTime,"yyyy-MM-dd").getTime() > DateUtils.stringToDate(endTmp,"yyyy-MM-dd").getTime() ){
endTime = endTmp;
}
} else{
return null;
}
int dayc=daysBetween(startTime,endTime);
BigDecimal rll = new BigDecimal(String.valueOf(ll)).divide(BigDecimal.valueOf(jxfs),10,BigDecimal.ROUND_HALF_UP);
BigDecimal lxje = hkAmount.multiply(rll).multiply(BigDecimal.valueOf(dayc));
interpayRo.setWithdrawalPc( bo.getWithdrawalPc());
interpayRo.setPlanInterpayDate( endTime);
interpayRo.setStartDate( startTime);
interpayRo.setEndDate( endTime );
interpayRo.setAddFlag("1");
interpayRo.setDays( dayc);
interpayRo.setRateMethod( transWrInfoBo.getRateMethod() );
interpayRo.setAnnualizedRate( transWrInfoBo.getActRate() );
interpayRo.setPrincipal( hkAmount);
interpayRo.setInterAmount( lxje.setScale(2, RoundingMode.HALF_UP));
return interpayRo;
}
/**
* 获取付息列表
* @param result
* @param pchList
*/
public static void getInterpayList( WithdrawalInfoRo result , FinancTransWrInfoBo transWrInfoBo , List<FinancTransWrListBo> pchList ) throws ParseException {
List<FinancTransWrInterpayRo> interpayRos = result.getTransWrInterpays();
if( interpayRos == null ){
interpayRos = new ArrayList<>();
}
String type = transWrInfoBo.getRatePayFreq();
for( FinancTransWrListBo bo : pchList){
boolean b = true;
String startTime = bo.getWithdrawalStartDate();
int phase = 0;//第几期
if( "MTHLY10".equals( type)) {
// 每月10日-在10号最近还款日期应该是当月
int dayTmp = Integer.parseInt((bo.getWithdrawalStartDate().split("-"))[2]);
if (dayTmp < 10) { //加入小于10号在当月开始第一笔还款
phase = -1;
}
}else if( "MTHLY21".equals( type)){
// 每月21日-在21号前最近还款日期应该是当月
int dayTmp = Integer.parseInt((bo.getWithdrawalStartDate().split("-"))[2]);
if (dayTmp < 21) { //加入小于10号在当月开始第一笔还款
phase = -1;
}
}else if( "Q21".equals( type)){
//当季度月份21一号前最近还款日是当月 期数为0开始
Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtils.stringToDate( bo.getWithdrawalStartDate(),"yyyy-MM-dd" ));
if( ( calendar.get(Calendar.MONTH)+1) %3==0 ){
//判断当前时间是季度月
int dayTmp = Integer.parseInt((bo.getWithdrawalStartDate().split("-"))[2]);
if (dayTmp < 21) { //加入小于10号在当月开始第一笔还款
phase = -1;
}
}
}
while ( b ){
FinancTransWrInterpayRo ro= getInterpayDetail( startTime ,++phase , transWrInfoBo , bo);
if( ro ==null ){
break;
}
b = DateUtils.stringToDate(bo.getWithdrawalEndDate(),"yyyy-MM-dd").getTime() > DateUtils.stringToDate(ro.getEndDate(),"yyyy-MM-dd").getTime();
startTime = ro.getEndDate();
interpayRos.add( ro);
}
}
result.setTransWrInterpays( interpayRos);
}
/**
* 测试案例:M - 1、开始日期每月都存在 2、开始日期部分月份不存在 例如31号
* MTHLY10/MTHLY21 案例:1、开始时间在还款日之前日期 <10 2、开始时间当天还款日 =10 3、开始时间在还款日期之后
* Q21 : 1、Q月份前 2、Q当月(还款日期前,当天,后)
* A:一年的,跨年的
* @param bo
* @return
*/
public static Result<WithdrawalInfoRo> getRepayPlanListNew ( WithdrawalInfoBo bo ){
try {
WithdrawalInfoRo withdrawalInfoRo = new WithdrawalInfoRo();
getRepayList( withdrawalInfoRo,bo.getTransWrLists());
getInterpayList( withdrawalInfoRo,bo.getTransWrInfo(),bo.getTransWrLists() );
return Result.success(withdrawalInfoRo);
}catch (Exception ex ){
ex.printStackTrace();
return Result.failed("还本付息计划生成失败");
}
}