按提款计划生成还本付息计划

/**
 * 计算两个日期之间的天数
 * @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("还本付息计划生成失败");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值