package com.hehenian.biz.service.trade.impl; import com.hehenian.biz.common.account.dataobject.PersonDo; import com.hehenian.biz.common.base.dataobject.PageDo; import com.hehenian.biz.common.base.result.IResult; import com.hehenian.biz.common.base.result.ResultSupport; import com.hehenian.biz.common.contant.Constants; import com.hehenian.biz.common.exception.BusinessException; import com.hehenian.biz.common.trade.IRepaymentService; import com.hehenian.biz.common.trade.RepayOperationType; import com.hehenian.biz.common.trade.dataobject.*; import com.hehenian.biz.component.account.IPersonComponent; import com.hehenian.biz.component.trade.*; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.*; /** * @author zhangyunhua * @version 1.0 * @since 1.0 */ @Service("repaymentService") public class RepaymentServiceImpl implements IRepaymentService { private final Logger logger = Logger.getLogger(this.getClass()); @Autowired private IRepaymentComponent repaymentComponent; // 还款的三种实现 @Autowired private IRepaymentManagerComponent normalRepayComponentImpl; @Autowired private IRepaymentManagerComponent preSettleRepayComponentImpl; @Autowired private IRepaymentManagerComponent compRepayComponentImpl; @Autowired private IAssignmentDebtComponent assignmentDebtComponent; @Autowired private IRepaymentRecordComponent repaymentRecordComponent; @Autowired private IPersonComponent personComponent; @Autowired private IInvestRepaymentComponent investRepaymentComponent; @Autowired private IBorrowComponent borrowComponent; /** * 根据条件查询列表,用于翻页 */ public PageDo selectRepaymentPage(Map<String, Object> parameterMap, PageDo page) { parameterMap.put(Constants.MYBATIS_PAGE, page); List<Map> pageList = repaymentComponent.selectRepaymentPage(parameterMap); page.setPage(pageList); return page; } /** * 更新 */ public int updateRepaymentById(RepaymentDo newRepaymentDo) { return repaymentComponent.updateRepaymentById(newRepaymentDo); } /** * 新增 */ public int addRepayment(RepaymentDo newRepaymentDo) { return repaymentComponent.addRepayment(newRepaymentDo); } /** * 删除 */ public int deleteById(Long id) { return repaymentComponent.deleteById(id); } /** * 根据ID 查询 * * @parameter id */ public RepaymentDo getById(Long id) { return repaymentComponent.getById(id); } /** * 根据条件查询列表 */ public List<RepaymentDo> selectRepayment(Map<String, Object> parameterMap) { return repaymentComponent.selectRepayment(parameterMap); } private IRepaymentManagerComponent getIRepaymentManagerComponent(String operationType) { if (RepayOperationType.NORMAL_REPAY.toString().equals(operationType)) { return normalRepayComponentImpl; } else if (RepayOperationType.PRE_SETTLE_REPAY.toString().equals(operationType)) { return preSettleRepayComponentImpl; } else if (RepayOperationType.COMP_REPAY.toString().equals(operationType)) { return compRepayComponentImpl; } else { return null; } } /** * 返回 提前结清对象,方便核对数据: 提前结清金额, 提前结清手续费等 * * @param operationType * 操作类型 * @param borrowId * 标的ID * @param payId * 还款id * @param userId * 借款人 * @return {@link} * See(com.hehenian.biz.component.trade.impl.RepaymentContext) * @author: zhangyunhmf * @date: 2014年11月26日上午9:11:04 */ public RepaymentContext buildContext(String operationType, long borrowId, long payId, long userId) { IRepaymentManagerComponent repayment = getIRepaymentManagerComponent(operationType); RepaymentContext rc = repayment.buildContext(payId, borrowId, userId, null, operationType, null, null); PersonDo person = personComponent.getByUserId(rc.getBorrow().getPublisher()); rc.getUserDo().setPerson(person); return rc; } /** * 还款服务入口 */ public IResult<Object> doRepay(String operationType, long borrowId, long payId, String outCustId, long userId, String username, String pwd, String webURL) { IRepaymentManagerComponent repayment = getIRepaymentManagerComponent(operationType); // 准备参数 RepaymentContext rc = repayment.buildContext(payId, borrowId, userId, username, operationType, outCustId, webURL); try { if (null == rc) { return buildResult(11); } // 检查完整性和合法性 int result = repayment.doCheck(rc); if (result != 0) { return buildResult(result); } // 更改成还款中的状态 repayment.lock(rc.getRepaymentDo()); // 记录还款 repaymentRecordComponent.logProcess(rc.getRepaymentDo(), operationType); // 调用汇付 IResult<Object> callResult = repayment.callChinaPnrService(rc); // 判断是否成功 if (!callResult.isSuccess()) { Integer errorIdx = (Integer) rc.getCallChinapnrErrorIndex(); if (errorIdx.intValue() < 1) { // 没有一条成功就返回页面 return callResult; } } // end 调用汇付 try { assignmentDebtComponent.updateDebtStatusFailure(borrowId); } catch (Exception e) { logger.error("标的id:" + borrowId + "失效债券转让失败"); } // 写出资人的流水,和可用金额 repayment.updatePublisherAmount(rc); // 汇付调用全部成功 更新数据库相关单据状态 if (callResult.isSuccess()) { repayment.updateStatus(rc); } repaymentRecordComponent.updateProcess(rc.getRepaymentDo(), operationType); if (!callResult.isSuccess()) { return new ResultSupport<Object>(false, "调用汇付部分成功, 部分失败:" + callResult.getErrorMessage()); } return new ResultSupport<Object>(true); } catch (Exception e) { logger.error(e); return new ResultSupport<Object>(false, e.getMessage()); } finally { // 如果失败解锁 repayment.unLock(rc.getRepaymentDo()); // 清理参数 rc.freeContext(); } } private IResult<Object> buildResult(int errorCode) { switch (errorCode) { case 1: return new ResultSupport<Object>(false, "找不到还款记录"); case 2: return new ResultSupport<Object>(false, "该笔还款已处理"); case 3: return new ResultSupport<Object>(false, "你的金额不够,请充值再操作"); case 4: return new ResultSupport<Object>(false, "你获取的还款记录信息不是最新的信息,请刷新重试"); case 5: return new ResultSupport<Object>(false, "你获取的还款记录信息不是最新的信息,该还款记录状态已经被更新"); case 6: return new ResultSupport<Object>(false, "你没有此还款记录操作权限"); case 7: return new ResultSupport<Object>(false, "此标的还款期数以还满"); case 8: return new ResultSupport<Object>(false, "没有找到要还款的数据"); case 9: return new ResultSupport<Object>(false, "检查数据过程中出错"); case 10: return new ResultSupport<Object>(false, "没有正确配置代偿账户"); case 11: return new ResultSupport<Object>(false, "准备还款数据过程中失败"); default: return new ResultSupport<Object>(false, "还款失败,未知错误"); } } /* * (no-Javadoc) <p>Title: addRepaymentFee</p> <p>Description: </p> * * @param repaymentFeeList * * @see * com.hehenian.biz.common.trade.IRepaymentService#addRepaymentFee(java. * util.List) */ public void addRepaymentFee(List<RepaymentFeeDo> repaymentFeeList) { repaymentComponent.addRepaymentFee(repaymentFeeList); } /* * (no-Javadoc) <p>Title: updateRepaymentStatus</p> <p>Description: </p> * * @param borrowId * * @param repayPeriod * * @param userId * * @see * com.hehenian.biz.common.trade.IRepaymentService#updateRepaymentStatus * (long, java.lang.String, long) */ @Override public void updateRepaymentStatus(long borrowId, String repayPeriod, long userId) { Map<String, Object> parameterMap = new HashMap<String, Object>(); parameterMap.put("borrowId", borrowId); parameterMap.put("repayPeriod", repayPeriod); List<RepaymentDo> repaymentList = repaymentComponent.selectRepayment(parameterMap); if (null == repaymentList || repaymentList.size() != 1) { throw new BusinessException("参数不对,查询不到对应的还款记录"); } RepaymentDo newRepaymentDo = repaymentList.get(0); List<InvestRepaymentDo> investRepaymentList = investRepaymentComponent.selectInvestInfoByRepayId(newRepaymentDo .getId()); for (InvestRepaymentDo irdo : investRepaymentList) { irdo.setRepayStatus(2); investRepaymentComponent.updateInvestRepaymentById(irdo); } borrowComponent.updateBorrowStatusAndHasDeadlineById(borrowId); borrowComponent.updateBorrowStatus(borrowId); newRepaymentDo.setRepayStatus(2); newRepaymentDo.setExecuteTime(new Date()); repaymentComponent.updateRepaymentById(newRepaymentDo); RepaymentRecordDo newRepaymentRecord = new RepaymentRecordDo(); newRepaymentRecord.setRemark(RepayOperationType.CLOSE_REPAY.name()); newRepaymentRecord.setCreateTime(new Date()); newRepaymentRecord.setOporator(userId); newRepaymentRecord.setProcessStatus("2"); newRepaymentRecord.setRepayAmount(0d); newRepaymentRecord.setRepayType("2"); newRepaymentRecord.setRepayId(newRepaymentDo.getId()); repaymentRecordComponent.addRepaymentRecord(newRepaymentRecord); } /* * (no-Javadoc) <p>Title: manualRepayment</p> <p>Description: </p> * * @param repaymentId * * @param ordId * * @param operateType * * @param realPrincipal * * @param realInterest * * @param fee603 * * @param fee902 * * @param fee901 * * @param fee903 * * @return * * @see * com.hehenian.biz.common.trade.IRepaymentService#manualRepayment(java. * lang.String, java.lang.String, java.lang.String, java.lang.String, * java.lang.String, java.lang.String, java.lang.String, java.lang.String, * java.lang.String) */ @Override public IResult<Object> manualRepayment(long repaymentId, long ordId, String operateType, double realPrincipal, double realInterest, double fee603, double fee902, double fee901, double fee903, String webURL) { IRepaymentManagerComponent repayment = this.getIRepaymentManagerComponent(operateType); RepaymentDo repaymentDo = this.repaymentComponent.getById(repaymentId); BorrowDo borrowDo = this.borrowComponent.getById(repaymentDo.getBorrowId()); RepaymentContext rc = repayment.buildContext(repaymentId, borrowDo.getId(), borrowDo.getPublisher(), "", operateType, "", webURL); List<InvestRepaymentWrap> investList = rc.getInvestList(); InvestRepaymentWrap investRepaymentWrap = null; for (InvestRepaymentWrap irWrap : investList) { if (ordId == irWrap.getInvestRepaymentDO().getId().longValue()) { investRepaymentWrap = irWrap; break; } } InvestRepaymentDo investRepaymentDO = investRepaymentWrap.getInvestRepaymentDO(); investRepaymentDO.setRecivedPrincipal(realPrincipal); investRepaymentDO.setRecivedInterest(realInterest); List<RepaymentFeeDo> proportionFeeList = new ArrayList<RepaymentFeeDo>(); // 代偿的时候不需要费用 if (!RepayOperationType.COMP_REPAY.toString().equals(operateType)) { if (fee902 > 0) { RepaymentFeeDo rf = new RepaymentFeeDo(); rf.setFeeCode(com.hehenian.biz.common.base.constant.Constants.FEE_CODE_CONSULT); rf.setHasAmount(fee902); rf.setInvestRepaymentId(ordId); rf.setRemark("手动还款"); rf.setLastUpdateDate(new Date()); rf.setRepaymentId(repaymentId); proportionFeeList.add(rf); } if (fee901 > 0) { RepaymentFeeDo rf = new RepaymentFeeDo(); rf.setFeeCode(com.hehenian.biz.common.base.constant.Constants.FEE_CODE_PRE); rf.setHasAmount(fee901); rf.setInvestRepaymentId(ordId); rf.setRemark("手动还款"); rf.setLastUpdateDate(new Date()); rf.setRepaymentId(repaymentId); proportionFeeList.add(rf); } if (fee903 > 0) { RepaymentFeeDo rf = new RepaymentFeeDo(); rf.setFeeCode(com.hehenian.biz.common.base.constant.Constants.FEE_CODE_SERVICE_CHARGE); rf.setHasAmount(fee903); rf.setInvestRepaymentId(ordId); rf.setRemark("手动还款"); rf.setLastUpdateDate(new Date()); rf.setRepaymentId(repaymentId); proportionFeeList.add(rf); } if (fee603 > 0) { RepaymentFeeDo rf = new RepaymentFeeDo(); rf.setFeeCode(com.hehenian.biz.common.base.constant.Constants.FEE_CODE_FX); rf.setHasAmount(fee603); rf.setInvestRepaymentId(ordId); rf.setRemark("手动还款"); rf.setLastUpdateDate(new Date()); rf.setRepaymentId(repaymentId); proportionFeeList.add(rf); } } if (proportionFeeList.size() > 1) { investRepaymentWrap.setProportionFeeList(proportionFeeList); } else { investRepaymentWrap.setProportionFeeList(null); } investList.clear(); investList.add(investRepaymentWrap); rc.setInvestList(investList); rc.getRepaymentDo().setFeeList(proportionFeeList); IResult<Object> result = repayment.callChinaPnrService(rc); if (result.isSuccess()) { rc.freshRepaymentAmount(); repayment.updatePublisherAmount(rc); } else { return result; } return new ResultSupport<Object>(true); } /* * (no-Javadoc) <p>Title: changeInvestRepaymentId</p> <p>Description: </p> * * @param repaymentId * * @return * * @see * com.hehenian.biz.common.trade.IRepaymentService#changeInvestRepaymentId * (long) */ @Override public void changeInvestRepaymentId(long repaymentId) { List<InvestRepaymentDo> investRepayList = this.investRepaymentComponent.selectInvestInfoByRepayId(repaymentId); if (null == investRepayList || investRepayList.isEmpty()) { return; } this.investRepaymentComponent.updateId(investRepayList); } }