212 lines
7.7 KiB
Java
212 lines
7.7 KiB
Java
package com.tenwa.reckon.util;
|
|
|
|
import java.math.BigDecimal;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import com.tenwa.reckon.bean.ConditionBean;
|
|
import com.tenwa.reckon.bean.FundRentPlanBean;
|
|
|
|
|
|
/**
|
|
*
|
|
* @author SHIHONGFEI
|
|
* @version 1.0
|
|
* @copyright (C) TENWA 2011
|
|
* @date 2011-2-17
|
|
* @desc ( 利息计算)
|
|
*/
|
|
public class InterestTools {
|
|
|
|
/**
|
|
*
|
|
* @param rentList
|
|
* 租金list
|
|
* @param leaseMoney
|
|
* 要测算的本金
|
|
* @param calRate
|
|
* 计算的利率 qzOrqm 期初还是期未
|
|
* @return
|
|
*/
|
|
|
|
/**
|
|
* 租金利息算法
|
|
*
|
|
* @Title: getInterestList
|
|
* @Description:
|
|
* @param
|
|
* @param rentList租金List
|
|
* @param
|
|
* @param leaseMoney总测算本金
|
|
* @param
|
|
* @param calRate测算利率
|
|
* @param
|
|
* @param qzOrqm期初或者期末
|
|
* @param
|
|
* @return
|
|
* @return List利息list
|
|
* @throws
|
|
*/
|
|
public List<String> getInterestList(List<String> rentList, String leaseMoney, String calRate, String qzOrqm) {
|
|
// 用于保留利息
|
|
List<String> interests = new ArrayList<String>();
|
|
String corpus_total = "0";
|
|
// 该期的利息
|
|
String inte = "";
|
|
String corpus = "";
|
|
String corpus_overage = "";
|
|
// 本金余额
|
|
corpus_overage = NumTools.formatNumberDoubleScale(leaseMoney, 2);
|
|
|
|
for (int i = 0; i < rentList.size(); i++) {// 循环租金list
|
|
//起租类型 注意: 期初 数字 1 字符串 period_type_1 #分割线# 期末 数字0 字符串 period_type_0
|
|
if ("1".equals(qzOrqm) && i == 0) {// 第一期且是期初时
|
|
corpus = rentList.get(i).toString();
|
|
inte = "0";
|
|
} else {
|
|
// 利息
|
|
inte = String.valueOf(Double.parseDouble(corpus_overage) * Double.parseDouble(calRate));// 剩余本金*利率
|
|
inte = NumTools.formatNumberDoubleScale(inte, 2);
|
|
// 本金
|
|
corpus = String.valueOf(Double.parseDouble(rentList.get(i).toString()) - Double.parseDouble(inte));// 租金-利息
|
|
corpus = NumTools.formatNumberDoubleScale(corpus, 2);
|
|
|
|
}
|
|
|
|
// 最后一期的利息=剩余的利息总合,本金仍然=租金-利息
|
|
if (i == rentList.size() - 1) {
|
|
// 本金 --总的本金-以前的本金和
|
|
corpus = String.valueOf(Double.parseDouble(leaseMoney) - Double.parseDouble(corpus_total));
|
|
corpus = NumTools.formatNumberDoubleScale(corpus, 2);
|
|
|
|
inte = String.valueOf(Double.parseDouble(rentList.get(i).toString()) - Double.parseDouble(corpus));
|
|
inte = NumTools.formatNumberDoubleScale(inte, 2);
|
|
|
|
}
|
|
|
|
corpus_total = String.valueOf(Double.parseDouble(corpus_total) + Double.parseDouble(corpus));
|
|
corpus_total = NumTools.formatNumberDoubleScale(corpus_total, 2);
|
|
|
|
// 本金余额
|
|
corpus_overage = String.valueOf(Double.parseDouble(corpus_overage) - Double.parseDouble(corpus));
|
|
corpus_overage = NumTools.formatNumberDoubleScale(corpus_overage, 2);
|
|
// 添加list
|
|
interests.add(inte);
|
|
|
|
}
|
|
|
|
return interests;
|
|
}
|
|
|
|
/**
|
|
* 根据传入参数 先按照frpb_old中的数据计算出在本次计算前的手续费分摊情况 然后按照frpb的数据再重新分摊剩余的手续费
|
|
*
|
|
* @param cb
|
|
* 商务条件
|
|
* @param frpb
|
|
* 本次计算出来的租金计划数据
|
|
* @param frpb_old
|
|
* 本次计算前的租金计划数据
|
|
* @param startList
|
|
* 本次计算租金的开始期项
|
|
* @return 返回全部的手续分摊情况
|
|
*/
|
|
public List<String> getHandlingChargeMoneyShare(ConditionBean cb, FundRentPlanBean frpb, FundRentPlanBean frpb_old, int startList) {
|
|
List<String> hand_interest_share = new ArrayList<String>();
|
|
List<String> corpus_overage = new ArrayList<String>();
|
|
BigDecimal handling_charge_money_total = new BigDecimal(cb.getHandlingChargeMoney());// 总手续费
|
|
//注释 new BigDecimal(cb.getCalTotalByCont())
|
|
BigDecimal sum_corpus = new BigDecimal(0);
|
|
if (handling_charge_money_total.compareTo(BigDecimal.ZERO) == 0) {// 偷懒做法,如果没有手续费就返回0
|
|
for (int i = 0; i < corpus_overage.size(); i++) {
|
|
hand_interest_share.add("0");
|
|
}
|
|
} else {// 开始计算手续费分摊值
|
|
//起租类型 注意: 期初 数字 1 字符串 period_type_1 #分割线# 期末 数字0 字符串 period_type_0
|
|
int period_type = Integer.parseInt(cb.getPeriodType());// 期初/期末
|
|
int grace = cb.getGrace();// 宽限期
|
|
// 按照原有的租金计划计算本次手续费分摊,只有在不是第一次测算时才有原租金计划 所以需要判断
|
|
if (frpb_old != null && frpb_old.getCorpusOverageBusinessList().size() > 0) {
|
|
corpus_overage = new ArrayList<String>(frpb_old.getCorpusOverageBusinessList());
|
|
} else {
|
|
corpus_overage = new ArrayList<String>(frpb.getCorpusOverageBusinessList());
|
|
}
|
|
// 先按照原租金计划计算出手续费分摊值,才知道本次的
|
|
hand_interest_share = InterestTools.getHandlingChargeMoneyShare(handling_charge_money_total, sum_corpus, corpus_overage, grace, period_type);
|
|
if (startList != 1) {// 如果不是第一期开始的就需要计算剩余的重新分摊
|
|
// 根据开始期项计算出需要分摊的手续费(因为变更和调息时之前的分摊不能动)
|
|
BigDecimal share_handling_charge_money = new BigDecimal(NumTools.getSumCorpusOverage(hand_interest_share, startList));// 需要分摊的剩余手续费
|
|
// 根据开始期数计算宽限期
|
|
if (startList > grace) {// 如果开始期数在宽限期之后那就直接设置宽限期没有
|
|
if (startList - grace != 1) {
|
|
period_type = 0;// 如果不在宽限期内,且不是正常租金计划第一期的时候都认为是期末
|
|
}
|
|
grace = 0;
|
|
} else {
|
|
grace = grace - startList;
|
|
}
|
|
// 计算新的剩余本金 从开始期数计算剩余本金
|
|
corpus_overage = new ArrayList<String>(frpb.getCorpusOverageBusinessList());
|
|
for (int i = 0; i < startList; i++) {
|
|
corpus_overage.remove(0);
|
|
}
|
|
// 从开始期数计算本金总和
|
|
sum_corpus = new BigDecimal(NumTools.getSumCorpusOverage(frpb.getCorpusBusinessList(), startList));
|
|
// 按照新的条件计算手续费分摊数据
|
|
List<String> share_hand_interest_temp = InterestTools.getHandlingChargeMoneyShare(share_handling_charge_money, sum_corpus, corpus_overage, grace, period_type);
|
|
// 移除掉原手续费分摊的开始期项后的数据并加入新计算的数据
|
|
for (int i = 0; i < share_hand_interest_temp.size(); i++) {
|
|
hand_interest_share.set(startList - 1 + i, share_hand_interest_temp.get(i));
|
|
}
|
|
}
|
|
}
|
|
return hand_interest_share;
|
|
}
|
|
|
|
/**
|
|
* 2013-1-6 孙传良 手续费分摊算法 <Br>
|
|
* 根据上一期剩余本金占所有剩余本金总和的比例计算当期手续费<Br>
|
|
* 如果是期初那么第一期不分摊手续费(因为在第一期的时候没有利息收入所以不分摊手续费)<Br>
|
|
* 如果手续费为0,则返回的每期手续费分摊为0
|
|
*
|
|
* @param hand_change_money
|
|
* @param sum_corpus
|
|
* @param corpus_overage
|
|
* @param grace
|
|
* @param period_type
|
|
* @return
|
|
*/
|
|
public static List<String> getHandlingChargeMoneyShare(BigDecimal hand_change_money, BigDecimal sum_corpus, List<String> corpus_overage, int grace, int period_type) {
|
|
List<String> interest = new ArrayList<String>();
|
|
List<String> corpus_overage_temp = new ArrayList<String>(corpus_overage);
|
|
// 如果是期初就把期初的那一期的剩余本金移除
|
|
if (period_type == 1) {
|
|
corpus_overage_temp.remove(grace);
|
|
}
|
|
// 把总本金作为第一期的剩余本金
|
|
corpus_overage_temp.add(0, sum_corpus.toString());
|
|
// 移除最后一期为0的剩余本金
|
|
corpus_overage_temp.remove(corpus_overage_temp.size() - 1);
|
|
// 计算剩余本金总和
|
|
BigDecimal sum_corpus_overage = new BigDecimal(NumTools.getSumCorpusOverage(corpus_overage_temp, 1));
|
|
BigDecimal share_money = new BigDecimal(0);
|
|
for (int i = 0; i < corpus_overage_temp.size(); i++) {
|
|
// 在之前的处理中已经把剩余本金往后延了一期所以这里取当期
|
|
BigDecimal this_corpus_overage = new BigDecimal(corpus_overage_temp.get(i).toString());
|
|
BigDecimal temp_money;
|
|
if (i != corpus_overage_temp.size()) {// 按照比例计算手续费分摊值
|
|
temp_money = hand_change_money.multiply(this_corpus_overage.divide(sum_corpus_overage, 20, BigDecimal.ROUND_HALF_UP)).setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
} else {// 最后一期的时候倒减 以 保证总手续费相等.
|
|
temp_money = hand_change_money.subtract(share_money).setScale(2, BigDecimal.ROUND_HALF_UP);
|
|
}
|
|
interest.add(temp_money.toString());
|
|
share_money = share_money.add(temp_money);
|
|
}
|
|
// 如果是期初则把期初的那一期设置为0
|
|
if (period_type == 1) {
|
|
interest.add(grace, "0");
|
|
}
|
|
return interest;
|
|
}
|
|
}
|