apzl_leasing/calc/com/tenwa/reckon/help/RentalServiceImpl.java

552 lines
18 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.

package com.tenwa.reckon.help;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.tenwa.reckon.bean.ConditionBean;
import com.tenwa.reckon.constant.Scale;
import com.tenwa.reckon.util.DateTools;
import com.tenwa.reckon.util.NumTools;
import com.tenwa.reckon.util.NumberUtils;
import com.tenwa.reckon.util.RateTools;
import com.tenwa.reckon.util.RentTools;
import com.tenwa.reckon.util.Tools;
/**
*
* @author SHIHONGFEI
* @version 1.0
* @copyright (C) TENWA 2011
* @date 2011-3-3
* @desc ( 不同的租金测算值pmt算租金根据期限之类的算出租金List并返回租金测算层)
*/
public class RentalServiceImpl {
/**
*
* ( 标准根据交易结构算出pmt租金值)
*
* @param cb
* @return
*/
public String getSignRentByCb(ConditionBean cb) {
// 1.根据年利率等信息,
// 中的getPreRate得到测算的租金利率
String preRate = RateTools.getPreRate(cb.getYearRate(), cb.getIncomeNumberYear(),cb.getRateAdjustType());
// 2.调用PMT方法得每期租金
String rent = RentTools.getPMT(preRate, cb.getIncomeNumber() + "", "-" + cb.getCleanLeaseMoney(), cb.getEquipEndValue(), cb.getPeriodType());
//sea 2014-03-10 等额租金-按租金计算年利率 情况下:每期租金置为界面输入的租金值,防止不正确的小数出现
String settleMethod = Tools.getDBStr( cb.getSettleMethod() );//租金计算方法 ,等额租金even_rent
String rentOrRate = Tools.getDBStr( cb.getRentOrRate() );//计算方式 按租金计算年利率 :rent 按年利率计算租金 :rate
if("even_rent".equals(settleMethod) && "rent".equals(rentOrRate)){
//TODO
}
//seaEND
//算出来的租金进行精度规整四舍五入小数点后保留2位
return new BigDecimal(rent).setScale(Scale.RENT_SCALE, BigDecimal.ROUND_HALF_UP).toString();
}
/**
*
* ( 其它测算方法可以重构此方法并返回租金list)
*
* @param cb
* @return
*/
public List<String> getRentListByCond(ConditionBean cb) {
// 1.根据年利率等信息,
// 中的getPreRate得到测算的租金利率
String preRate = RateTools.getPreRate(cb.getYearRate(), cb.getIncomeNumberYear(),cb.getRateAdjustType());
String cleanLeaseMoney = cb.getCleanLeaseMoney();
if(new BigDecimal(cb.getCleanLeaseMoney()).compareTo(BigDecimal.ZERO) > 0 ){
cleanLeaseMoney = "-"+cb.getCleanLeaseMoney();
}
String rent = "";
if(cb.getRentOrRate() != null && cb.getRentOrRate().equals("rent")){
rent = cb.getRentValue().toString();
}else{
BigDecimal finalPayment = new BigDecimal(cb.getFinalPayment());
if(finalPayment.compareTo(BigDecimal.ZERO) != 0) {
rent = new BigDecimal(RentTools.getPMT(preRate, cb.getIncomeNumber() + "", cleanLeaseMoney, finalPayment.toString(), cb.getPeriodType())).toString();
} else {
rent = new BigDecimal(RentTools.getPMT(preRate, cb.getIncomeNumber() + "", cleanLeaseMoney, cb.getEquipEndValue(), cb.getPeriodType())).toString();
}
if(cb.getRentRound().length()>0){
rent=NumberUtils.rentRound(rent, cb.getRentRound(),cb.getRentRoundType());
}
}
// 3.是否有宽限期判断,宽限期租金列表计算
List<String> rent_list = new ArrayList<String>();
rent_list = getGraceRentList(cb, rent_list, preRate);
// 4.正常租金列表计算
rent_list = getNormalRentList(cb, rent_list, rent);
return rent_list;
}
/**
*
* 众联车辆等额租金
*
* @param cb
* @return
*/
public List<String> getRentListByCondWithZL(ConditionBean cb) {
// 1.根据年利率等信息,
// 中的getPreRate得到测算的租金利率
String preRate = RateTools.getPreRate(cb.getYearRate(), cb.getIncomeNumberYear(),cb.getRateAdjustType());
String cleanLeaseMoney = cb.getShare().toString();
if(cb.getShare().compareTo(BigDecimal.ZERO) > 0 ){
cleanLeaseMoney = "-"+cleanLeaseMoney;
}
String rent = "";
if(cb.getRentOrRate() != null && cb.getRentOrRate().equals("rent")){
rent = cb.getRentValue().toString();
}else{
rent =new BigDecimal(RentTools.getPMT(preRate, cb.getIncomeNumber() + "", cleanLeaseMoney, cb.getEquipEndValue(), cb.getPeriodType())).toString();
if(cb.getRentRound().length()>0){
rent=NumberUtils.rentRound(rent, cb.getRentRound(),cb.getRentRoundType());
}
}
// 3.是否有宽限期判断,宽限期租金列表计算
List<String> rent_list = new ArrayList<String>();
rent_list = getGraceRentList(cb, rent_list, preRate);
// 4.正常租金列表计算
rent_list = getNormalRentList(cb, rent_list, rent);
return rent_list;
}
/**
* 等额租金 日利率
* @param dateList
* @param cb
* @return
*/
public List<String> getRentListByCond(ConditionBean cb,List<String> dateList){
String rate=new BigDecimal(cb.getYearRate()).divide(new BigDecimal(100)).toString();
String rent="";
if(cb.getRentOrRate() != null && cb.getRentOrRate().equals("rent")){
rent = cb.getRentValue().toString();
}else{
rent=RentTools.getDayPmt(dateList,rate,cb.getCleanLeaseMoney(),cb.getEquipEndValue(),cb.getStartDate(), cb.getGrace());
if(cb.getRentRound().length()>0){
rent=NumberUtils.rentRound(rent, cb.getRentRound(),cb.getRentRoundType());
}
}
// 3.是否有宽限期判断,宽限期租金列表计算
List<String> rent_list = new ArrayList<String>();
rent_list = getGraceRentList(cb, rent_list,cb.getYearRate(),dateList);
// 4.正常租金列表计算
rent_list = getNormalRentList(cb, rent_list, rent);
return rent_list;
}
/**
*
* ( 均息法下获得租金列表,并调整最后一期的均息法下的本息)
*
* @param corpus
* 总本金
* @param endValues
* 剩余本金
* @param corpus
* 本金集合
* @param interest
* 利息集合
* @return 返回租金集合
*/
public List<String> getRentListByCond(String leas_money, String endValues, List<String> corpus, List<String> interest,ConditionBean cb) {
List<String> rent_list = new ArrayList<String>();
BigDecimal corpus_total = new BigDecimal("0");
for (int i = 0; i < corpus.size(); i++) {
BigDecimal rent = new BigDecimal(corpus.get(i).toString()).add(new BigDecimal(interest.get(i).toString())).setScale(RentTools.getRentAccuracy(), BigDecimal.ROUND_HALF_UP);
if(cb.getRentRound().length()>0){
rent=new BigDecimal(NumberUtils.rentRound(rent.toString(),cb.getRentRound(),cb.getRentRoundType()));
}
rent_list.add(rent.toString());
// 因为租金元整过,所以这里要重新元整利息
BigDecimal inteTemp = rent.subtract(new BigDecimal(corpus.get(i).toString()).setScale(RentTools.getInterestAccuracy(), BigDecimal.ROUND_HALF_UP));
interest.set(i, inteTemp.toString());
if (i < corpus.size() - 1) {
corpus_total = corpus_total.add(new BigDecimal(corpus.get(i)));
}
}
// 调整最后一期本息
String last_corpus = new BigDecimal(leas_money).subtract(new BigDecimal(endValues)).subtract(corpus_total).setScale(RentTools.getAccuracy(), BigDecimal.ROUND_HALF_UP).toString();
corpus.set(corpus.size() - 1, last_corpus);
interest.set(interest.size() - 1, new BigDecimal(rent_list.get(rent_list.size() - 1).toString()).subtract(new BigDecimal(corpus.get(corpus.size() - 1).toString())).setScale(RentTools.getAccuracy(), BigDecimal.ROUND_HALF_UP).toString());
return rent_list;
}
/**
*
* ( 正常租金列表计算)
*
* @param cb
* @param rent_list
* @param rent
* @return
*/
public List<String> getNormalRentList(ConditionBean cb, List<String> rent_list, String rent) {
BigDecimal finalPayment = new BigDecimal(cb.getFinalPayment());
for (int i = 0; i < cb.getIncomeNumber(); i++) {
if(i == cb.getIncomeNumber() - 1 && finalPayment.compareTo(BigDecimal.ONE) != 0 && "final_payment_method02".equals(cb.getFinalPaymentMethod())) {
rent_list.add(finalPayment.add(new BigDecimal(rent)).toString());
} else {
rent_list.add(rent);
}
}
return rent_list;
}
/**
*
* ( 宽限期租金计算)
*
* @param cb
* @return
*/
public List<String> getGraceRentList(ConditionBean cb, List<String> rent_list, String preRate) {
if (cb != null && cb.getGrace() > 0) {
// 算出宽限期的租金
String newRent = new BigDecimal(cb.getCleanLeaseMoney()).multiply(new BigDecimal(preRate)).toString();
for (int i = 0; i < cb.getGrace(); i++) {
rent_list.add(NumTools.formatNumberDoubleScale(newRent, RentTools.getRentAccuracy()));
}
}
return rent_list;
}
/**
* 等额租金按日利率 计算宽限期租金
* @param cb
* @param rent_list
* @param yearDate
* @param dateList
* @return
*/
public List<String> getGraceRentList(ConditionBean cb,List<String> rent_list,String yearDate,List<String> dateList){
int grace=cb.getGrace();//宽限期
BigDecimal year = new BigDecimal(360);
BigDecimal rate=new BigDecimal(yearDate);
String startDate=cb.getStartDate();
if(cb!=null&&grace>0){
for(int i=0;i<grace;i++){
String planDate =dateList.get(i);
Long dayDiff = DateTools.getDateDiff(planDate,startDate );
startDate = planDate;
String newRent=new BigDecimal(cb.getCleanLeaseMoney()).multiply(rate).multiply(new BigDecimal(dayDiff)).divide(new BigDecimal(100)).divide(year,2,BigDecimal.ROUND_HALF_UP).toString();
rent_list.add(newRent);
}
}
return rent_list;
}
/**
*
* ( 不规则租金测算List)
*
* @param cb
* @param rent_list
* @return
*/
public List<String> getDeviRentList(ConditionBean cb, List<String> rent_list, String index) {
//
String rent = getSignRentByCb(cb);
// 4.正常租金列表计算
// rent_list = getNormalRentList(cb, rent_list, rent);
// 重新给后面的元素赋值
for (int i = Integer.parseInt(index); i < rent_list.size(); i++) {
rent_list.set(i, rent);
// index = String.valueOf(Integer.parseInt(index) + 1);
}
return rent_list;
}
/**
*
* ( 不规则租金测算,参照合成) 2011-12-6
* 增加年利率计划参数.根据租金计划中的年利率算相关值
*
* @param cb
* @param rentAdjustList
* @return
*/
@SuppressWarnings("unchecked")
public List<String> getDeviRentList(ConditionBean cb, String[] rentAdjustList, List<String> year_rate) {
// 将不规则数组转化为List列表 String []rent_adjust_arr
List<String> l_rent_adjust = Arrays.asList(rentAdjustList);
// 1.根据年利率等信息,
// 中的getPreRate得到测算的租金利率
// 2011-12-6 修改为从集合中拿年利率
// String preRate = RateTools.getPreRate(cb.getYear_rate(),
// cb.getIncome_number_year());
// String preRate = RateTools.getPreMonthRate(cb.getYear_rate());
// 3.是否有宽限期判断,宽限期租金列表计算
List<String> rent_list = new ArrayList<String>();
// 宽限期的租金调整
int grace = cb.getGrace();
if (grace > 0) {
rent_list = getDevGraceRentList(cb, l_rent_adjust, grace, year_rate);
}
// 得到调整期的本金和
String btotal_charge = getCharCorTotal(l_rent_adjust, year_rate, cb);
// 得到不调整期的本金系数和
String btotal_nocharge = getNoCharCorTotal(l_rent_adjust, year_rate, cb);
if (btotal_nocharge.toString().equals("0")) {
btotal_nocharge = "1";
}
// 总的
String preRate = RateTools.getPreRate(year_rate.get(year_rate.size() - 1), cb.getIncomeNumberYear(),cb.getRateAdjustType());
String endValue = String.valueOf(Double.parseDouble(cb.getEquipEndValue()) / Math.pow(1 + Double.parseDouble(preRate), Double.valueOf(cb.getIncomeNumber())));
String rent = new BigDecimal(String.valueOf(new BigDecimal(cb.getCleanLeaseMoney()).subtract(new BigDecimal(endValue)))).subtract(new BigDecimal(btotal_charge)).divide(new BigDecimal(btotal_nocharge), 20, BigDecimal.ROUND_HALF_UP).toString();
// 构建新的租金列表
rent_list = getDevNewRentList(l_rent_adjust, rent, rent_list, cb.getGrace());
return rent_list;
}
/**
*
* ( 得到宽限期的调整租金)
*
* @param cb
* @param l_rent_adjust
* @param grace
* @param year_rate
* 年利率集合
* @return 返回宽限期内的调整租金后的租金列表
*/
private List<String> getDevGraceRentList(ConditionBean cb, List<String> l_rent_adjust, int grace, List<String> year_rate) {
List<String> devGrace = new ArrayList<String>();
// String preRate = RateTools.getPreRate(cb.getYear_rate(),
// cb.getIncome_number_year());
String preRate = "";
// 本金总和
String corpus = cb.getCleanLeaseMoney();
// 因为宽限期不多,就每一期单独计算
for (int i = 0; i < grace; i++) {
preRate = RateTools.getPreRate(year_rate.get(i), cb.getIncomeNumberYear(),cb.getRateAdjustType());
if (l_rent_adjust.get(i).toString().equals("")) {// 如果不调整就是本金*利率
devGrace.add(new BigDecimal(corpus).multiply(new BigDecimal(preRate)).toString());
} else {
devGrace.add(l_rent_adjust.get(i).toString());
// 2011-11-14 宽限期调整 不对后续测试有任何影响
// corpus=new BigDecimal(corpus).subtract(new
// BigDecimal(l_rent_adjust.get(i).toString())
// .subtract(new BigDecimal(corpus).multiply(new
// BigDecimal(preRate)))).toString();
}
}
// 2011-11-14 宽限期调整 不对后续测试有任何影响
// cb.setCalTotalByCont(corpus);//宽限期之后的本金总值
return devGrace;
}
/**
*
* ( 构建新的租金列表)
*
* @param l_rent_adjust
* @param rent
* @return
*/
private List<String> getDevNewRentList(List<String> l_rent_adjust, String rent, List<String> rent_list, int grace) {
// List rent_list = new ArrayList();
int igrace = grace;
for (int i = igrace; i < l_rent_adjust.size(); i++) {
if ("".equals(l_rent_adjust.get(i).toString())) {// 如这期不调整时
rent_list.add(rent);
} else {// 有调整时
rent_list.add(l_rent_adjust.get(i).toString());
}
}
return rent_list;
}
/**
*
* ( 得到变更后的本金和)
*
* @param l_rent_adjust
* @param preRate
* @return
*/
private String getCharCorTotal(List<String> l_rent_adjust, List<String> year_rate, ConditionBean cb) {
String pv_str = "0";// 用于保存变更的本金和
// 得到变更的租金列表下标值,并以数组返回
String[] i_array = RentTools.getAdjustIds(l_rent_adjust, cb.getGrace());
String preRate = "";
int num = 0;
if (cb.getPeriodType().toString().equals("0")) {// 如果期末要加1
num = 1;
}
for (int i = 0; i < i_array.length; i++) {
preRate = RateTools.getPreRate(year_rate.get(i), cb.getIncomeNumberYear(),cb.getRateAdjustType());
String iValue = new String(i_array[i]);
// if ("".equals(iValue)){
// iValue="0";
// }
// 2011-04-20宽限期不算进期中所以
iValue = String.valueOf(Integer.parseInt(iValue) - cb.getGrace());
pv_str = String.valueOf(Double.parseDouble(pv_str) + Double.parseDouble(l_rent_adjust.get(Integer.parseInt(i_array[i])).toString()) / Math.pow(1 + Double.parseDouble(preRate), Double.valueOf(Integer.parseInt(iValue) + num)));
// logger.info("=double算出=" +pv_str);
// logger.info(btotal_charge.doubleValue());
}
return pv_str;
}
/**
*
* ( 得到不变更的本金系数和)
*
* @param l_rent_adjust
* @param preRate
* @return
*/
private String getNoCharCorTotal(List<String> l_rent_adjust, List<String> year_rate, ConditionBean cb) {
// 得到不调整期的本金系数和
String dTotal = "0";// 用于保存不变更的本金系数和
// 得到不变更的租金列表下标值,并以数组返回
String[] i_no_array = RentTools.getNoAdjustIds(l_rent_adjust, cb.getGrace());
String preRate = "";
int num = 0;
if (cb.getPeriodType().toString().equals("0")) {// 如果期末要加1
num = 1;
}
for (int i = 0; i < i_no_array.length; i++) {
preRate = RateTools.getPreRate(year_rate.get(i), cb.getIncomeNumberYear(),cb.getRateAdjustType());
String inoValue = new String(i_no_array[i]);
// if ("".equals(inoValue)){
// inoValue="0";
// }
// 2011-04-20宽限期不算进期中所以
inoValue = String.valueOf(Integer.parseInt(inoValue) - cb.getGrace());
dTotal = String.valueOf(Double.parseDouble(dTotal) + Double.parseDouble("1") / Math.pow(1 + Double.parseDouble(preRate), Double.valueOf(Integer.parseInt(inoValue) + num)));
}
return dTotal;
}
/**
* scl (根据FundRentPlanBean和租金调整值测算每期租金)
*
* @param frpb
* FundRentPlanBean
* @param rentAdjustList
* @return
*/
@SuppressWarnings("unchecked")
public List<String> getDeviRentList(ConditionBean cdb, List<String> year_rate_list, String[] rentAdjustList) {
// 将不规则数组转化为List列表 String []rent_adjust_arr
List<String> l_rent_adjust = Arrays.asList(rentAdjustList);
// 得到调整期的本金和
String btotal_charge = getCharCorTotal(l_rent_adjust, year_rate_list, cdb.getGrace());
// 得到不调整期的本金系数和
String btotal_nocharge = getNoCharCorTotal(l_rent_adjust, year_rate_list, cdb.getGrace());
// 得到总的测算本金
if (btotal_nocharge.toString().equals("0")) {
btotal_nocharge = "1";
}
String rent = new BigDecimal(cdb.getCleanLeaseMoney()).subtract(new BigDecimal(btotal_charge)).divide(new BigDecimal(btotal_nocharge), 20, BigDecimal.ROUND_HALF_UP).toString();
// 构建新的租金列表
List<String> rent_list = new ArrayList<String>();
rent_list = getDevNewRentList(l_rent_adjust, rent, rent_list, cdb.getGrace());
return rent_list;
}
/**
* scl ( 得到变更后的本金和)
*
* @param l_rent_adjust
* 调整值
* @param year_rate_list
* 年利率
* @return
*/
private String getCharCorTotal(List<String> l_rent_adjust, List<String> year_rate_list, int grace) {
String pv_str = "0";// 用于保存变更的本金和
// 得到变更的租金列表下标值,并以数组返回
String[] i_array = RentTools.getAdjustIds(l_rent_adjust, grace);
for (int i = 0; i < i_array.length; i++) {
String iValue = new String(i_array[i]);
// 2011-04-20宽限期不算进期中所以
iValue = String.valueOf(Integer.parseInt(iValue) - grace);
pv_str = String.valueOf(Double.parseDouble(pv_str) + Double.parseDouble(l_rent_adjust.get(Integer.parseInt(i_array[i])).toString()) / Math.pow(1 + Double.parseDouble(year_rate_list.get(i).toString()), Double.valueOf(Integer.parseInt(iValue) + 1)));
}
return pv_str;
}
/**
* scl 得到不变更的本金系数和)
*
* @param l_rent_adjust
* @param year_rate_list
* @return
*/
private String getNoCharCorTotal(List<String> l_rent_adjust, List<String> year_rate_list, int grace) {
// 得到不调整期的本金系数和
String dTotal = "0";// 用于保存不变更的本金系数和
// 得到不变更的租金列表下标值,并以数组返回
String[] i_no_array = RentTools.getNoAdjustIds(l_rent_adjust, grace);
for (int i = 0; i < i_no_array.length; i++) {
String inoValue = new String(i_no_array[i]);
// 2011-04-20宽限期不算进期中所以
inoValue = String.valueOf(Integer.parseInt(inoValue) - grace);
dTotal = String.valueOf(Double.parseDouble(dTotal) + Double.parseDouble("1") / Math.pow(1 + Double.parseDouble(year_rate_list.get(i).toString()), Double.valueOf(Integer.parseInt(inoValue) + 1)));
}
return dTotal;
}
public List<String> getRentRemainList(List<String> rentList) {
List<String> result = new ArrayList<String>();
String first = "0";
for (int i = rentList.size() - 1; i >= 0; i--) {
result.add(0, first);
first = new BigDecimal(first).add(new BigDecimal(rentList.get(i))).toString();
}
return result;
}
}