/** * @Project: hehenian-biz-service * @Package com.hehenian.biz.service.trade.impl * @Title: AssignmentDebtServiceImpl.java * @Description: TODO * @author: liuzgmf * @date 2014年9月26日 上午11:32:16 * @Copyright: HEHENIAN Co.,Ltd. All rights reserved. * @version V1.0 */ package com.hehenian.biz.service.trade.impl; import com.hehenian.biz.common.account.dataobject.AccountUserDo; import com.hehenian.biz.common.base.result.IResult; import com.hehenian.biz.common.base.result.ResultSupport; import com.hehenian.biz.common.exception.BusinessException; import com.hehenian.biz.common.trade.IAssignmentDebtService; import com.hehenian.biz.common.trade.dataobject.*; import com.hehenian.biz.common.trade.dataobject.AuctionDebtDo.AuctionStatus; import com.hehenian.biz.common.util.CalculateUtils; import com.hehenian.biz.component.account.IUserComponent; import com.hehenian.biz.component.trade.*; import com.hehenian.biz.facade.account.AccountType; import com.hehenian.biz.facade.account.IAccountManagerService; import com.hehenian.biz.facade.account.parameter.InParameter; import com.hehenian.biz.facade.account.parameter.OutParameter; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateUtils; import org.apache.log4j.Logger; import org.codehaus.jackson.JsonGenerationException; import org.codehaus.jackson.map.JsonMappingException; import org.codehaus.jackson.map.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.text.DecimalFormat; import java.text.ParseException; import java.util.*; /** * * @author: liuzgmf * @date 2014年9月26日 上午11:32:16 */ @Service("assignmentDebtService") public class AssignmentDebtServiceImpl implements IAssignmentDebtService { private final Logger logger = Logger.getLogger(this.getClass()); @Autowired private IAccountManagerService accountManagerService; @Autowired private IAssignmentDebtComponent assignmentDebtComponent; @Autowired private IUserComponent userComponent; @Autowired private IInvestComponent investComponent; @Autowired private IBorrowComponent borrowComponent; @Autowired private IInvestRepaymentComponent investRepaymentComponent; @Autowired private IAuctionDebtComponent auctionDebtComponent; @Autowired private IReconciliationComponent reconciliationComponent; @Override public IResult<?> addAssignmentDebt(AssignmentDebtDo assignmentDebtDo) { IResult<String> result = new ResultSupport<String>(); try { boolean success = assignmentDebtComponent.isHaveAssignmentDebt(assignmentDebtDo.getInvestId(), assignmentDebtDo.getAlienatorId()); if (!success) { throw new BusinessException("该笔投资已转让!"); } // 债权转让申请必须在还款日期五天前 InvestRepaymentDo investRepaymentDo = investRepaymentComponent.getNoRepayRecordRecently( assignmentDebtDo.getInvestId(), assignmentDebtDo.getAlienatorId()); if (investRepaymentDo == null || new Date().after(DateUtils.addDays(investRepaymentDo.getRepayDate(), -5))) { throw new BusinessException("还款日前五日内不能进行债权转让!"); } assignmentDebtDo.setDebtStatus(1);// 1-审核中 assignmentDebtComponent.addAssignmentDebt(assignmentDebtDo); result.setSuccess(true); } catch (BusinessException e) { result.setSuccess(false); result.setErrorMessage(e.getMessage()); logger.warn("债权转让申请失败,投资ID[" + assignmentDebtDo.getInvestId() + "]," + e.getMessage()); } catch (Exception e) { result.setSuccess(false); result.setErrorMessage("操作失败,请稍后再试!"); logger.error(e.getMessage(), e); } return result; } public static void main(String[] args) throws ParseException { Date date = DateUtils.addDays(DateUtils.parseDate("20141119", new String[] { "yyyyMMdd" }), -5); System.out.println(DateFormatUtils.format(date, "yyyyMMdd")); } @Override public IResult<?> updateDebtAudit(AssignmentDebtDo assignmentDebtDo) { IResult<String> result = new ResultSupport<String>(); try { assignmentDebtComponent.updateDebtAudit(assignmentDebtDo); result.setSuccess(true); } catch (BusinessException e) { result.setSuccess(false); result.setErrorMessage(e.getMessage()); logger.error(e.getMessage(), e); } catch (Exception e) { result.setSuccess(false); result.setErrorMessage("操作失败,请稍后再试!"); logger.error(e.getMessage(), e); } return result; } @Override public IResult<?> addPurchaseDebt(Long auctionUserId, Long debtId, Double auctionPrice) { IResult<String> result = new ResultSupport<String>(); try { // 校验债权记录以及用户账户余额等 checkPurchaseDebt(auctionUserId, debtId, auctionPrice); // 新增债权认购信息 Long auctionDebtId = addAuctionDebt(auctionUserId, debtId, auctionPrice); // 发送债权转让申请请求到汇付 return creditAssign(auctionDebtId); } catch (BusinessException e) { result.setSuccess(false); result.setErrorMessage(e.getMessage()); logger.warn("债权[" + debtId + "]认购失败" + e.getMessage()); } catch (Exception e) { result.setSuccess(false); result.setErrorMessage("操作失败,请稍后再试!"); logger.error(e.getMessage(), e); } return result; } /** * 新增债权转让认购信息 * * @param auctionerId * @param debtId * @param auctionPrice * @return * @author: liuzgmf * @date: 2014年10月8日下午3:34:12 */ private Long addAuctionDebt(Long auctionerId, long debtId, double auctionPrice) { AuctionDebtDo auctionDebtDo = new AuctionDebtDo(); auctionDebtDo.setId(investComponent.getAutoIncrementId()); auctionDebtDo.setUserId(auctionerId); auctionDebtDo.setDebtId(debtId); auctionDebtDo.setAuctionPrice(auctionPrice); auctionDebtDo.setAuctionTime(new Date()); auctionDebtDo.setAutiontimes(1); auctionDebtDo.setAuctionStatus(AuctionStatus.PROCESSING); return auctionDebtComponent.addAuctionDebt(auctionDebtDo); } /** * 债权转让购买 * * @param auctionUserId * @param debtId * @param auctionPrice * @return * @author: liuzgmf * @date: 2014年9月29日上午11:23:14 */ private IResult<?> creditAssign(Long auctionDebtId) { InParameter inParameter = new InParameter(); inParameter.setOrdId(auctionDebtId + ""); inParameter.setRetUrl("creditAssign.do"); inParameter.setBgRetUrl("creditAssignBg.do"); AuctionDebtDo auctionDebtDo = auctionDebtComponent.getById(auctionDebtId); AssignmentDebtDo assignmentDebtDo = assignmentDebtComponent.getById(auctionDebtDo.getDebtId()); AccountUserDo userDo = userComponent.getById(assignmentDebtDo.getAlienatorId()); inParameter.getParams().put("SellCustId", userDo.getUsrCustId()); InvestDo investDo = investComponent.getById(assignmentDebtDo.getInvestId()); inParameter.getParams().put("CreditAmt", CalculateUtils.sub(investDo.getRecivedPrincipal(), investDo.getHasPrincipal())); inParameter.getParams().put("CreditDealAmt", auctionDebtDo.getAuctionPrice()); inParameter.getParams().put("BidDetails", createBidDetails(auctionDebtDo.getUserId(), auctionDebtDo.getDebtId())); inParameter.getParams().put("Fee", "0.00"); inParameter.getParams().put("DivDetails", ""); AccountUserDo auctionUserDo = userComponent.getById(auctionDebtDo.getUserId()); inParameter.getParams().put("BuyCustId", auctionUserDo.getUsrCustId()); inParameter.getParams().put("OrdDate", DateFormatUtils.format(new Date(), "yyyyMMdd")); inParameter.getParams().put("MerPriv", ""); OutParameter outParameter = accountManagerService.creditAssign(inParameter, AccountType.CHINAPNR); IResult<String> result = new ResultSupport<String>(); if (outParameter.isSuccess()) { result.setSuccess(true); result.setModel((String) outParameter.getParams().get("htmlText")); } else { result.setSuccess(false); result.setErrorMessage(outParameter.getRespDesc()); } return result; } /** * 创建债权转让明细信息 * * @param userId * @param debtId * @return * @author: liuzgmf * @date: 2014年9月29日下午2:37:56 */ private String createBidDetails(Long userId, Long debtId) { Map<String, Object> borrowerDetailMap = new LinkedHashMap<String, Object>(); AssignmentDebtDo assignmentDebtDo = assignmentDebtComponent.getById(debtId); BorrowDo borrowDo = borrowComponent.getById(assignmentDebtDo.getBorrowId()); AccountUserDo userDo = userComponent.getById(borrowDo.getPublisher()); borrowerDetailMap.put("BorrowerCustId", userDo.getUsrCustId()); InvestDo investDo = investComponent.getById(assignmentDebtDo.getInvestId()); DecimalFormat df = new DecimalFormat("##0.00"); borrowerDetailMap.put("BorrowerCreditAmt", df.format(CalculateUtils.sub(investDo.getRecivedPrincipal(), investDo.getHasPrincipal()))); borrowerDetailMap.put("PrinAmt", "0.00"); List<Object> borrowerDetails = new ArrayList<Object>(); borrowerDetails.add(borrowerDetailMap); Map<String, Object> bidDetailMap = new LinkedHashMap<String, Object>(); if (assignmentDebtDo.getParentId() != null && assignmentDebtDo.getParentId().longValue() > 0) { AuctionDebtDo auctionDebtDo = auctionDebtComponent.getByDebtId(assignmentDebtDo.getParentId()); bidDetailMap.put("BidOrdId", auctionDebtDo.getId()); } else { bidDetailMap.put("BidOrdId", assignmentDebtDo.getInvestId()); } bidDetailMap.put("BidOrdDate", DateFormatUtils.format(investDo.getInvestTime(), "yyyyMMdd")); bidDetailMap.put("BidCreditAmt", df.format(CalculateUtils.sub(investDo.getRecivedPrincipal(), investDo.getHasPrincipal()))); bidDetailMap.put("BorrowerDetails", borrowerDetails); List<Object> bidDetails = new ArrayList<Object>(); bidDetails.add(bidDetailMap); Map<String, Object> params = new LinkedHashMap<String, Object>(); params.put("BidDetails", bidDetails); try { ObjectMapper objectMapper = new ObjectMapper(); return objectMapper.writeValueAsString(params); } catch (JsonGenerationException e) { throw new RuntimeException(e.getMessage(), e); } catch (JsonMappingException e) { throw new RuntimeException(e.getMessage(), e); } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } } /** * 校验用户是否可以购买债权转让 * * @param userId * @param auctionDebtId * @param auctionPrice * @return * @author: liuzgmf * @date: 2014年9月26日下午4:46:13 */ private boolean checkPurchaseDebt(Long auctionerId, Long debtId, Double auctionPrice) { AssignmentDebtDo assignmentDebtDo = assignmentDebtComponent.getById(debtId); if (assignmentDebtDo == null) { throw new BusinessException("债权转让记录不存在!"); } AccountUserDo userDo = userComponent.getById(auctionerId); if (userDo == null) { throw new BusinessException("用户记录不存在!"); } Date endDate = DateUtils.addDays(assignmentDebtDo.getPublishTime(), assignmentDebtDo.getAuctionDays()); if (new Date().after(endDate)) { throw new BusinessException("债权转让记录已过期!"); } if (assignmentDebtDo.getAlienatorId().longValue() == auctionerId.longValue()) { throw new BusinessException("不能购买自己转让的的债权!"); } if (CalculateUtils.lt(userDo.getUsableSum(), auctionPrice)) { throw new BusinessException("账户可用余额不足!"); } BorrowDo borrowDo = borrowComponent.getById(assignmentDebtDo.getBorrowId()); if (borrowDo.getPublisher().longValue() == auctionerId.longValue()) { throw new BusinessException("借款者不能购买该债权!"); } if (assignmentDebtDo.getDebtStatus().intValue() != 2) { throw new BusinessException("非转让中的债权,购买失败!"); } return true; } /** * 校验用户是否可以购买债权转让 * * @param auctionDebtId * @param auctionPrice * @return * @author: liuzgmf * @date: 2014年11月3日下午2:41:22 */ private boolean checkPurchaseDebt(long auctionDebtId, double auctionPrice) { AuctionDebtDo auctionDebtDo = auctionDebtComponent.getById(auctionDebtId); AccountUserDo userDo = userComponent.getById(auctionDebtDo.getUserId()); if (CalculateUtils.lt(userDo.getUsableSum(), auctionPrice)) { throw new BusinessException("账户可用余额不足!"); } AssignmentDebtDo assignmentDebtDo = assignmentDebtComponent.getById(auctionDebtDo.getDebtId()); if (assignmentDebtDo.getDebtStatus().intValue() != 2) { throw new BusinessException("非转让中的债权,购买失败!"); } return true; } @Override public IResult<?> updatePurchaseDebt(long auctionDebtId, double auctionPrice) { IResult<String> result = new ResultSupport<String>(); try { // 校验债权转让是否已成功处理 AuctionDebtDo auctionDebtDo = auctionDebtComponent.getById(auctionDebtId); if (auctionDebtDo.getAuctionStatus().equals(AuctionStatus.SUCCESS)) { result.setSuccess(true); return result; } // 校验债权转让数据是否合法 checkPurchaseDebt(auctionDebtId, auctionPrice); // 平台认购债权处理 assignmentDebtComponent.updatePurchaseDebt(auctionDebtId, auctionPrice); result.setSuccess(true); } catch (BusinessException e) { result.setSuccess(false); result.setErrorMessage(e.getMessage()); logger.warn("债权认购[" + auctionDebtId + "]失败" + e.getMessage()); } catch (Exception e) { result.setSuccess(false); result.setErrorMessage("操作失败,请稍后再试!"); logger.error(e.getMessage(), e); } return result; } @Override public Boolean updateAuctionStatus(String ordId, AuctionStatus targetStatus, AuctionStatus sourceStatus) { return auctionDebtComponent.updateAuctionStatus(ordId, targetStatus, sourceStatus); } @Override public Map<String, Object> trfReconciliation(String beginDate, String endDate, String pageNum) { InParameter inParameter = new InParameter(); if (StringUtils.isEmpty(beginDate) || StringUtils.isEmpty(endDate)) { beginDate = DateFormatUtils.format(DateUtils.addDays(new Date(), -5), "yyyyMMdd"); endDate = DateFormatUtils.format(DateUtils.addDays(new Date(), 1), "yyyyMMdd"); } inParameter.getParams().put("BeginDate", beginDate); inParameter.getParams().put("EndDate", endDate); inParameter.getParams().put("PageNum", (StringUtils.isEmpty(pageNum) ? 1 : pageNum)); inParameter.getParams().put("PageSize", 1000); OutParameter outParameter = accountManagerService.trfReconciliation(inParameter, AccountType.CHINAPNR); return outParameter.getParams(); } @Override public Map<String, Object> reconciliation(String beginDate, String endDate, String pageNum, String queryTransType) { InParameter inParameter = new InParameter(); if (StringUtils.isEmpty(beginDate) || StringUtils.isEmpty(endDate)) { beginDate = DateFormatUtils.format(DateUtils.addDays(new Date(), -5), "yyyyMMdd"); endDate = DateFormatUtils.format(DateUtils.addDays(new Date(), 1), "yyyyMMdd"); } inParameter.getParams().put("BeginDate", beginDate); inParameter.getParams().put("EndDate", endDate); inParameter.getParams().put("PageNum", (StringUtils.isEmpty(pageNum) ? 1 : pageNum)); inParameter.getParams().put("PageSize", 1000); inParameter.getParams().put("QueryTransType", queryTransType); OutParameter outParameter = accountManagerService.reconciliation(inParameter, AccountType.CHINAPNR); return outParameter.getParams(); } @Override public Map<String, Object> saveReconciliation(String beginDate, String endDate, String pageNum) { InParameter inParameter = new InParameter(); if (StringUtils.isEmpty(beginDate) || StringUtils.isEmpty(endDate)) { beginDate = DateFormatUtils.format(DateUtils.addDays(new Date(), -5), "yyyyMMdd"); endDate = DateFormatUtils.format(DateUtils.addDays(new Date(), 1), "yyyyMMdd"); } inParameter.getParams().put("BeginDate", beginDate); inParameter.getParams().put("EndDate", endDate); inParameter.getParams().put("PageNum", (StringUtils.isEmpty(pageNum) ? 1 : pageNum)); inParameter.getParams().put("PageSize", 1000); OutParameter outParameter = accountManagerService.saveReconciliation(inParameter, AccountType.CHINAPNR); return outParameter.getParams(); } @Override public Map<String, Object> cashReconciliation(String beginDate, String endDate, String pageNum) { InParameter inParameter = new InParameter(); if (StringUtils.isEmpty(beginDate) || StringUtils.isEmpty(endDate)) { beginDate = DateFormatUtils.format(DateUtils.addDays(new Date(), -5), "yyyyMMdd"); endDate = DateFormatUtils.format(DateUtils.addDays(new Date(), 1), "yyyyMMdd"); } inParameter.getParams().put("BeginDate", beginDate); inParameter.getParams().put("EndDate", endDate); inParameter.getParams().put("PageNum", (StringUtils.isEmpty(pageNum) ? 1 : pageNum)); inParameter.getParams().put("PageSize", 1000); OutParameter outParameter = accountManagerService.cashReconciliation(inParameter, AccountType.CHINAPNR); return outParameter.getParams(); } @Override public Map<String, Object> queryAcctDetails(Long userId) { InParameter inParameter = new InParameter(); AccountUserDo userDo = userComponent.getById(userId); inParameter.getParams().put("UsrCustId", userDo.getUsrCustId()); OutParameter outParameter = accountManagerService.queryAcctDetails(inParameter, AccountType.CHINAPNR); return outParameter.getParams(); } }