/** * @Project: hehenian-biz-service * @Package com.hehenian.biz.service.trade.impl * @Title: RepaymentContext.java * @Description: TODO * @author: zhangyunhmf * @date 2014年10月22日 上午11:37:52 * @Copyright: HEHENIAN Co.,Ltd. All rights reserved. * @version V1.0 */ package com.hehenian.biz.common.trade.dataobject; import java.math.BigDecimal; import java.util.HashMap; import java.util.List; import java.util.Map; import com.hehenian.biz.common.account.dataobject.AccountUserDo; import com.hehenian.biz.common.util.CalculateUtils; /** * * @author: zhangyunhmf * @date 2014年10月22日 上午11:37:52 */ public class RepaymentContext implements java.io.Serializable { /** * @Fields serialVersionUID : TODO */ private static final long serialVersionUID = -85214436067671611L; /** * 上下文环境变量KEY */ public static final String CONTEXT_BORROW = "borrow"; // 标的对象 public static final String CONTEXT_REPAYMENT = "repaymentDo"; // 还款对象 public static final String CONTEXT_BORROW_ID = "borrowId"; // 标的ID public static final String CONTEXT_REPAYMENT_ID = "repaymentId"; // 还款id public static final String CONTEXT_INVEST_LIST = "investList"; // 投资列表 public static final String CONTEXT_USER_ID = "userId"; // 当期用户ID public static final String CONTEXT_OUT_CUST_ID = "outCustId"; // 出资汇付账户 public static final String CONTEXT_REPAY_OPERATION_TYPE = "repayOperationType"; // 还款类型: // 正常还款,提前结清,代偿 public static final String CONTEXT_USER_NAME = "username"; // 当前用户名 public static final String CONTEXT_NEED_SUM = "needSum"; // 应还款总金额 public static final String CONTEXT_WEB_URL = "CONTEXT_WEB_URL"; // 系统url public static final String CONTEXT_CALL_ERROR_IDX = "CALL_ERROR_IDX"; // 调用汇付失败的记录下标号 // fundrecord 资金变动记录remark模板 public static final String fundrecord_remark_template = "fundrecord_remark_repay.ftl"; public static final String fundrecord_remark_url = "fundrecord_remark_url.ftl"; public static final String fundrecord_remark_template_fi = "fundrecord_remark_repay_fi.ftl"; public static final String fundrecord_remark_template_invest = "fundrecord_remark_repay_invest.ftl"; public static final String sms_invest_template = "sms_repay_invest.ftl"; // 投资人邮件模板 /** * 罚金 */ public static final String FEE_FI = "FEE_FI"; /** * 手续费 */ public static final String FEE_REPAY = "FEE_REPAY"; /** * 咨询费 */ public static final String FEE_CONSULT = "FEE_CONSULT"; /** * 提前结清手续费 */ public static final String FEE_PRE_SETTLE = "FEE_PRE_SETTLE"; /** * 还款期数的ID ,对于提前结清可能是当前期, 如果不满3期则为第三期, 总期数不足三期时为最后一期 */ private long repaymentId; /** * 标的ID */ private long borrowId; /** * 还款用户, 对于代偿是代偿账号对应的用户 */ private long userId; /** * userId对应的名称 */ private String username; /** * 操作类型: 正常还款,代偿, 提前结清 */ private String operationType; /** * 出款人汇付id, 正常还款是借款人, 代偿是代偿方 */ private String outCustId; /** * 系统URL */ private String webURL; /** * repaymentId对应的对象, 对于提前结清是一个汇总数据 */ private RepaymentDo repaymentDo; /** * borrowId对应的标的对象 */ private BorrowDo borrow; /** * userId 对应的用户对象 */ private AccountUserDo userDo; /** * 回款List */ private List<InvestRepaymentWrap> investList; /** * 调用汇付失败时回款List的下标 */ private int callChinapnrErrorIndex = -1; public RepaymentContext(long repaymentId, long borrowId, long userId, String username, String operationType, String outCustId, String webURL) { this.repaymentId = repaymentId; this.borrowId = borrowId; this.userId = userId; this.username = username; this.operationType = operationType; this.outCustId = outCustId; this.webURL = webURL; } /** * 释放对象 * * @author: zhangyunhmf * @date: 2014年10月22日下午4:03:38 */ public void freeContext() { this.repaymentDo = null; this.borrow = null; this.userDo = null; if (null != this.investList) { this.investList.clear(); } this.investList = null; } /** * 统计回款list的总回款金额 */ public double getInvestListTotalAmount() { double repayTotalSum = 0; // 应还总金额 // 从回款list统计应回款金额总额 for (int i = 0, size = investList.size(); i < size; i++) { InvestRepaymentWrap irWrap = investList.get(i); InvestRepaymentDo investRepay = irWrap.getInvestRepaymentDO(); repayTotalSum = CalculateUtils.add(repayTotalSum, investRepay.getRecivedTotalAmount()); } return repayTotalSum; } /** * 统计回款list的本金总额 */ public double getInvestListTotalPrincipal() { double repayTotalSum = 0; // 应还本金总额 // 从回款list统计应回款金额总额 for (int i = 0, size = investList.size(); i < size; i++) { InvestRepaymentWrap irWrap = investList.get(i); InvestRepaymentDo investRepay = irWrap.getInvestRepaymentDO(); repayTotalSum = CalculateUtils.add(repayTotalSum, investRepay.getRecivedPrincipal() == null ? 0 : investRepay.getRecivedPrincipal()); } return repayTotalSum; } /** * 统计回款list的利息总额 */ public double getInvestListTotalInterest() { double repayTotalSum = 0; // 应还利息总额 // 从回款list统计应回款金额总额 for (int i = 0, size = investList.size(); i < size; i++) { InvestRepaymentWrap irWrap = investList.get(i); InvestRepaymentDo investRepay = irWrap.getInvestRepaymentDO(); repayTotalSum = CalculateUtils.add(repayTotalSum, investRepay.getRecivedInterest() == null ? 0 : investRepay.getRecivedInterest()); } return repayTotalSum; } /** * 统计回款列表总的代偿金额 * * @return * @author: zhangyunhmf * @date: 2014年11月26日下午2:57:42 */ public double getCompAmont() { double repayTotalSum = 0; // 应还代偿金额总额 // 从回款list统计应回款金额总额 for (int i = 0, size = investList.size(); i < size; i++) { InvestRepaymentWrap irWrap = investList.get(i); InvestRepaymentDo investRepay = irWrap.getInvestRepaymentDO(); if (investRepay.getIsWebRepay().intValue() == 2) { repayTotalSum = CalculateUtils.add(repayTotalSum, investRepay.getRecivedTotalAmount()); } } return repayTotalSum; } /** * 分摊费用 * * @author: zhangyunhmf * @date: 2014年10月8日下午2:03:51 */ public void splitFee() { List<RepaymentFeeDo> repayFeelist = this.repaymentDo.getFeeList(); if (null == repayFeelist || repayFeelist.isEmpty()) {// 没有费用需要分摊 return; } if (null == this.investList || this.investList.size() < 1) { return; } double repayTotalSum = this.getInvestListTotalAmount(); // 从回款list统计应回款金额总额 // =应还总金额 // 开始为每一笔回款分摊费用 // 每个费用的分摊逻辑,按占比, 分摊费用=(投资人应收总额/借款人应还款总额)* 总费用 for (int j = 0; j < repayFeelist.size(); j++) { RepaymentFeeDo rf = repayFeelist.get(j); double baseAmount = CalculateUtils.sub(rf.getStillAmount(), rf.getHasAmount()); // 应分摊金额 double proportionFee = 0; if (0 >= baseAmount) {// 0 不需要分摊 continue; } double totalFeeSum = 0; // 累计分摊 int size = investList.size() - 1; for (int i = 0; i < size; i++) { InvestRepaymentWrap irWrap = investList.get(i); InvestRepaymentDo investRepay = irWrap.getInvestRepaymentDO(); // 分摊费用(投资人应收总额/借款人应还款总额)* 总费用 // 按占比分摊 proportionFee = CalculateUtils.round( CalculateUtils.splitByRate(baseAmount, investRepay.getRecivedTotalAmount(), repayTotalSum), 2,BigDecimal.ROUND_DOWN); totalFeeSum = CalculateUtils.add(totalFeeSum, proportionFee); RepaymentFeeDo rfd = new RepaymentFeeDo(); rfd.setHasAmount(proportionFee); rfd.setFeeCode(rf.getFeeCode()); irWrap.addProportionFee(rfd); rfd.setRepaymentId(this.getRepaymentId()); // 当前还款ID }// end 费用列表的循环 // 最后一个用减法 InvestRepaymentWrap irWrap = investList.get(size); proportionFee = CalculateUtils.sub(baseAmount, totalFeeSum); RepaymentFeeDo rfd = new RepaymentFeeDo(); rfd.setHasAmount(proportionFee); rfd.setFeeCode(rf.getFeeCode()); irWrap.addProportionFee(rfd); rfd.setRepaymentId(this.getRepaymentId()); // 当前还款ID }// end investList 循环 } /** * 汇付,为了能重复还款,允许部分成功 需要记录成功交易的金额 * * @author: zhangyunhmf * @date: 2014年10月23日下午1:04:23 */ public void freshRepaymentAmount() { List<RepaymentFeeDo> rpfList = this.repaymentDo.getFeeList(); double hasP = 0; double hasI = 0; Map<String, Double> feeRealDeductAmountMap = new HashMap<String, Double>(); // 统计成功的金额 for (InvestRepaymentWrap irWrap : investList) { if (!irWrap.isSuccess()) {// 成功参与统计 continue; } // 统计实际已收本金和利息 InvestRepaymentDo ir = irWrap.getInvestRepaymentDO(); hasP = CalculateUtils.add(hasP, ir.getRecivedPrincipal()); hasI = CalculateUtils.add(hasI, ir.getRecivedInterest()); // 统计费用 :手续费,提前结清手续费,咨询费 List<RepaymentFeeDo> proportionList = irWrap.getProportionFeeList(); if (null != proportionList) { for (RepaymentFeeDo pf : proportionList) { Double realDeductAmount = feeRealDeductAmountMap.get(pf.getFeeCode()); if (null == realDeductAmount) { realDeductAmount = 0d; } realDeductAmount = CalculateUtils.add(realDeductAmount, pf.getHasAmount()); feeRealDeductAmountMap.put(pf.getFeeCode(), Double.valueOf("" + realDeductAmount)); } } }// end 统计成功的金额 // 更新费用实际已收 if (null != rpfList) { for (RepaymentFeeDo rpf : rpfList) { Double realDeductAmount = feeRealDeductAmountMap.get(rpf.getFeeCode()); rpf.setHasAmount(realDeductAmount); } } // end 开始统计已经成功扣除的本金利息,罚金,手续费,提前结清手续费,咨询费 this.repaymentDo.setHasPi(hasP + hasI); } /** * @return repaymentId */ public long getRepaymentId() { if (null != this.repaymentDo) { return this.repaymentDo.getId(); } return repaymentId; } /** * @param repaymentId * the repaymentId to set */ public void setRepaymentId(long repaymentId) { this.repaymentId = repaymentId; } /** * @return borrowId */ public long getBorrowId() { return borrowId; } /** * @param borrowId * the borrowId to set */ public void setBorrowId(long borrowId) { this.borrowId = borrowId; } /** * @return userId */ public long getUserId() { return userId; } /** * @param userId * the userId to set */ public void setUserId(long userId) { this.userId = userId; } /** * @return username */ public String getUsername() { return username; } /** * @param username * the username to set */ public void setUsername(String username) { this.username = username; } /** * @return operationType */ public String getOperationType() { return operationType; } /** * @param operationType * the operationType to set */ public void setOperationType(String operationType) { this.operationType = operationType; } /** * @return outCustId */ public String getOutCustId() { return outCustId; } /** * @param outCustId * the outCustId to set */ public void setOutCustId(String outCustId) { this.outCustId = outCustId; } /** * @return webURL */ public String getWebURL() { return webURL; } /** * @param webURL * the webURL to set */ public void setWebURL(String webURL) { this.webURL = webURL; } /** * @return repaymentDo */ public RepaymentDo getRepaymentDo() { return repaymentDo; } /** * @param repaymentDo * the repaymentDo to set */ public void setRepaymentDo(RepaymentDo repaymentDo) { this.repaymentDo = repaymentDo; } /** * @return borrow */ public BorrowDo getBorrow() { return borrow; } /** * @param borrow * the borrow to set */ public void setBorrow(BorrowDo borrow) { this.borrow = borrow; } /** * @return userDo */ public AccountUserDo getUserDo() { return userDo; } /** * @param userDo * the userDo to set */ public void setUserDo(AccountUserDo userDo) { this.userDo = userDo; } /** * @return investList */ public List<InvestRepaymentWrap> getInvestList() { return investList; } /** * @param investList * the investList to set */ public void setInvestList(List<InvestRepaymentWrap> investList) { this.investList = investList; } /** * @return the callChinapnrErrorIndex */ public int getCallChinapnrErrorIndex() { return callChinapnrErrorIndex; } /** * @param callChinapnrErrorIndex * the callChinapnrErrorIndex to set */ public void setCallChinapnrErrorIndex(int callChinapnrErrorIndex) { this.callChinapnrErrorIndex = callChinapnrErrorIndex; } }