package com.hehenian.biz.service.trade.impl;
import com.hehenian.agreement.common.share.FileClient;
import com.hehenian.agreement.common.utils.AgreementEnum;
import com.hehenian.biz.common.account.dataobject.AccountUserDo;
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.contant.FundConstant;
import com.hehenian.biz.common.exception.BusinessException;
import com.hehenian.biz.common.trade.IInvestService;
import com.hehenian.biz.common.trade.dataobject.*;
import com.hehenian.biz.common.util.CalculateUtils;
import com.hehenian.biz.common.util.DateUtil;
import com.hehenian.biz.common.util.JsonUtil;
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 com.hehenian.biz.service.dao.AbstractBaseDaoImpl;
import com.ibm.icu.text.DecimalFormat;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import javax.annotation.Resource;
/**
* User: liuwtmf
* Date: 2014/9/28
* Time: 9:22
*/
@Service("investService")
public class InvestServiceImpl implements IInvestService {
private static final Logger LOGGER = Logger.getLogger(InvestServiceImpl.class);
@Autowired
private IInvestComponent investComponent;
@Autowired
private IBorrowComponent borrowComponent;
@Autowired
private IAccountManagerService accountManagerService;
@Autowired
private IUserComponent userComponent;
@Autowired
private IFundrecordComponent fundrecordComponent;
@Autowired
private IInvestRepaymentComponent investRepaymentComponent;
@Autowired
private IAssignmentDebtComponent assignmentDebtComponent;
@Resource
private JdbcTemplate sp2pJdbcTemplate;
@Override public InvestDo getById(int id) {
return null;
}
@Override public List<InvestDo> selectInvest(Map<String, Object> parameterMap) {
return null;
}
@Override public int updateInvestById(InvestDo newInvestDo) {
return 0;
}
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("0.00");
@Override public IResult<?> addInvest(InvestDo newInvestDo, Long usrCustId, int userGroup, String usableSum) {
BorrowDo borrowDo = borrowComponent.getById(newInvestDo.getBorrowId());
LOGGER.info("borrowDo:"+borrowDo);
IResult<String> result = new ResultSupport<String>();
if (borrowDo != null) {
if (borrowDo.getBorrowStatus() == 2) {
long publisher = borrowDo.getPublisher();
if (newInvestDo.getInvestor() != publisher) {
if (usrCustId > 0) {
int borrowGroup = borrowDo.getBorrowGroup();
if (borrowGroup == 0 || userGroup == borrowGroup) {
if (borrowDo.getBorrowAmount() >= (newInvestDo.getInvestAmount() + borrowDo
.getHasInvestAmount())) {
if (Double.parseDouble(usableSum) >= newInvestDo.getInvestAmount()) {
InvestDo investDo = new InvestDo();
// investDo.setBorrowId(newInvestDo.getBorrowId());
investDo.setInvestTime(new Date());
investDo.setDeadline(borrowDo.getDeadline());
investDo.setMonthRate(borrowDo.getAnnualRate() / 12 * 100);
investDo.setInvestor(newInvestDo.getInvestor());
investDo.setOriInvestor(newInvestDo.getInvestor());
investDo.setFlag(newInvestDo.getFlag());
investDo.setSourceFrom(newInvestDo.getSourceFrom());
int i = investComponent.addInvest(investDo);
if (i > 0) {
InParameter inParameter = new InParameter();
inParameter.setOrdId(investDo.getId() + "");
inParameter.getParams().put("OrdDate",DateUtil.dateToYMD(new Date()));
inParameter.getParams().put("TransAmt",DECIMAL_FORMAT.format(newInvestDo.getInvestAmount() ));
AccountUserDo accountUserDo = userComponent.getById(investDo.getInvestor());
inParameter.getParams().put("UsrCustId",
accountUserDo.getUsrCustId() + "");
// JSONObject borrowerDetail = new
// JSONObject();
Map<String, Object> borrowerDetail = new HashMap<String, Object>();
AccountUserDo borrowUser = userComponent.getById(publisher);
borrowerDetail.put("BorrowerCustId",borrowUser.getUsrCustId()+"");
borrowerDetail.put("BorrowerAmt", DECIMAL_FORMAT.format(
newInvestDo.getInvestAmount()));
// 汇付还款总额为借款金额*(1+利率).改为1防止出现手续费过多出现:本次还款金额加上已还金额超过还款总额的情况
borrowerDetail.put("BorrowerRate","1.00");
String borrowrDetailStr = "";
try {
borrowrDetailStr = JsonUtil
.toString(borrowerDetail);
} catch (IOException e1) {
borrowrDetailStr = "";
LOGGER.error(e1);
}
inParameter.getParams().put(
"BorrowerDetails",
"[" + borrowrDetailStr + "]");
inParameter.getParams().put("borrowId", newInvestDo.getBorrowId() + "");
inParameter.setRetUrl("borrowInvestCallback.do");
inParameter.setBgRetUrl("");
FundrecordDo fundDo = new FundrecordDo();
fundrecordComponent.addFundrecord(fundDo);
fundrecordComponent.deleteById(fundDo.getId());
inParameter.getParams().put("FreezeOrdId",fundDo.getId()+"");
try {
OutParameter outParameter = accountManagerService.initiativeTender(inParameter, AccountType.CHINAPNR);
if (outParameter.isSuccess()) {
result.setSuccess(true);
result.setModel((String)outParameter.getParams().get("htmlText"));
} else {
result.setSuccess(false);
result.setErrorMessage(outParameter.getRespDesc());
}
}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);
}
}
}else{
//可用余额不足
result.setSuccess(false);
result.setErrorMessage("可用余额不足");
}
}else{
//投资总额超过可投总额
result.setSuccess(false);
result.setErrorMessage("投资总额超过可投总额");
}
}
}else {
//没有注册汇付
result.setSuccess(false);
result.setErrorMessage("没有注册汇付");
}
}else{
//不能投自己发布的标的
result.setSuccess(false);
result.setErrorMessage("不能投自己发布的标的");
}
}else{
//标的不在投标中的状态
result.setSuccess(false);
result.setErrorMessage("标的不在投标中的状态");
}
}else{
//标的不存在
result.setSuccess(false);
result.setErrorMessage("标的不存在");
}
return result;
}
@Override public int deleteById(int id) {
return 0;
}
@Override public IResult<?> addInvestCallback(InvestDo investDo) {
IResult<Integer> result = new ResultSupport<Integer>();
InvestDo localInvestDo = investComponent.getById(investDo.getId());
BorrowDo borrowDo = borrowComponent.getById(investDo.getBorrowId());
if (localInvestDo == null){
//记录不存在
result.setSuccess(false);
result.setErrorMessage("记录不存在");
}else if (localInvestDo.getTrxId()>0){
//记录已处理
// result.setSuccess(false);
result.setSuccess(true);
}else{
//更新标的数据
//
borrowDo.setInvestNum(borrowDo.getInvestNum()+1);
borrowDo.setHasInvestAmount(borrowDo.getHasInvestAmount() + investDo.getInvestAmount());
int j = borrowComponent.updateBorrowInvest(borrowDo);
if( j>0 ){
//更新成功
localInvestDo.setBorrowId(investDo.getBorrowId());
localInvestDo.setInvestAmount(investDo.getInvestAmount());
localInvestDo.setRealAmount(investDo.getInvestAmount());
localInvestDo.setTrxId(investDo.getTrxId());
localInvestDo.setInvestNumber("ZQ"+DateUtil.dateToYMD(new Date())+LPAD(StringUtils.right(investDo.getId()+"",5),5));
int i = investComponent.updateInvest(localInvestDo);
if (i>0){
//查询标的是否满标
//如果满标 就设置标的状态为满标
if (borrowDo.getBorrowAmount() <= borrowDo.getHasInvestAmount()) {
borrowDo.setBorrowStatus(Constants.BORROW_STATUS_FULL);
borrowComponent.updateStatus(borrowDo);
}
//修改用户的可用余额和冻结金额
try {
userComponent.updateAmount(-investDo.getInvestAmount(),investDo.getInvestAmount(),localInvestDo.getInvestor());
}catch (Exception e){
LOGGER.error(e.getMessage(),e);
LOGGER.error("修改用户金额失败");
}
result.setSuccess(true);
}else{
result.setSuccess(false);
result.setErrorMessage("操作失败,请稍后再试!");
}
}else{
//失败
//解冻金额
InParameter inParameter = new InParameter();
inParameter.setOrdId(investDo.getTrxId() + "");
inParameter.setTrxId(investDo.getTrxId() + "");
OutParameter outParameter = accountManagerService.usrUnFreeze(inParameter, AccountType.CHINAPNR);
if (!outParameter.isSuccess()) {
result.setSuccess(false);
result.setErrorMessage(outParameter.getRespDesc());
}else{
result.setSuccess(false);
result.setErrorMessage("标的已满,投标失败!");
}
}
}
return result;
}
private String LPAD(String x,int length){
while (x.length()<length){
x = "0" + x;
}
return x;
}
@Override
public IResult<?> discardBorrow(long borrowId){
BorrowDo borrowDo = borrowComponent.getById(borrowId);
IResult<Integer> result = new ResultSupport<Integer>();
if (borrowDo!=null && (borrowDo.getBorrowStatus()==Constants.BORROW_STATUS_FULL || borrowDo.getBorrowStatus()==Constants.BORROW_STATUS_NOT_FULL)){
borrowDo.setBorrowStatus(Constants.BORROW_STATUS_DISCARD);
int i = borrowComponent.updateStatus(borrowDo);
if (i>0){
result.setSuccess(true);
// 修改标的状态成功
List<InvestDo> investDos = investComponent.queryByBorrowId(borrowId);
if (investDos!=null){
StringBuilder sb = new StringBuilder();
for (InvestDo investDo : investDos) {
InParameter inParameter = new InParameter();
inParameter.setOrdId(investDo.getTrxId() + "");
inParameter.setTrxId(investDo.getTrxId() + "");
OutParameter outParameter = accountManagerService.usrUnFreeze(inParameter, AccountType.CHINAPNR);
if (outParameter.isSuccess()){
//修改用户可用余额 冻结金额
Boolean aBoolean = userComponent.updateAmount(investDo.getInvestAmount(), -investDo.getInvestAmount(),
investDo.getInvestor());
LOGGER.info("update user amount:"+aBoolean);
//添加资金流水
FundrecordDo fundrecordDo = new FundrecordDo();
fundrecordDo.setUserId(investDo.getInvestor());
fundrecordDo.setFundMode(FundConstant.UNFREEZE_INVEST);
fundrecordDo.setHandleSum(investDo.getInvestAmount());
fundrecordDo.setOperateType(-1);
AccountUserDo userDo = userComponent.getById(investDo.getInvestor());
fundrecordDo.setUsableSum(userDo.getUsableSum());
fundrecordDo.setFreezeSum(userDo.getFreezeSum());
Double dueinSum = investComponent.getDueinSum(investDo.getInvestor());
fundrecordDo.setDueinSum(dueinSum == null ? 0.00 : dueinSum);
fundrecordDo.setRecordTime(new Date());
String remark = "投标失败解冻投标金额"+investDo.getInvestAmount()+"元";
fundrecordDo.setRemarks(remark);
fundrecordDo.setIncome(investDo.getInvestAmount());
fundrecordDo.setSpending(0.0);
try {
fundrecordComponent.addFundrecord(fundrecordDo);
}catch (Exception e){
LOGGER.error("插入资金记录失败");
LOGGER.error(e.getMessage(),e);
}
}else {
//解冻失败
String msg = "投资"+investDo.getId()+"解冻失败,金额"+investDo.getInvestAmount()+",汇付返回:"+outParameter.getRespDesc();
sb.append(msg).append(";\n");
LOGGER.error(msg);
}
}
if (sb.length()>0){
result.setSuccess(false);
result.setErrorMessage(sb.toString());
}
}
}
}
return result;
}
/* (no-Javadoc)
* <p>Title: selectInvestSuccessRecordPage</p>
* <p>Description: </p>
* @param parameterMap
* @param page
* @return
* @see com.hehenian.biz.common.trade.IInvestService#selectInvestSuccessRecordPage(java.util.Map, com.hehenian.biz.common.base.dataobject.PageDo)
*/
@Override
public PageDo selectInvestSuccessRecordPage(Map<String, Object> parameterMap, PageDo page) {
parameterMap.put(Constants.MYBATIS_PAGE, page);
String currentUser = String.valueOf((Long)parameterMap.get("investor"));
List<Map<String,Object>> investList = investComponent.selectInvestSuccessRecordPage(parameterMap);
if(null == investList || investList.isEmpty()) return page;
// 封装处理翻页查询的结果 ,处理hessian 不支持的数据类型
Map<String,List<Integer>> rowMap = new HashMap<String,List<Integer>>();
List<Long> investIdList = new ArrayList<Long>();
for(int i = 0 ; i < investList.size() ; i++ ){
Map<String,Object> row = investList.get(i);
long investId = (Long)row.get("investId");
BigDecimal annualRate = row.get("annualRate") == null ? BigDecimal.ZERO :(BigDecimal)row.get("annualRate");
row.put("annualRate", CalculateUtils.round(annualRate.doubleValue()));
BigDecimal realAmount = row.get("realAmount") == null ? BigDecimal.ZERO :(BigDecimal)row.get("realAmount");
row.put("realAmount", CalculateUtils.round(realAmount.doubleValue()));
String investTime = "";
try{
investTime = DateUtil.dateToString((Date)row.get("investTime"));
}catch(Exception e){
LOGGER.error("investTime format error");
}
row.put("investTime", investTime);
row.put("currentUser", currentUser);
//如果是投资去取债券转让信息
AssignmentDebtDo ad = assignmentDebtComponent.getSuccessInvestAssignmentDebt(investId, new Long(currentUser));
if(null != ad){
AuctionDebtDo auddo = ad.getAuctionDebtDo();
if(null != auddo){
row.put("auctionStatus", auddo.getAuctionStatus());
//auddo.getAuctionTime();
}
row.put("alienatorId", ad.getAlienatorId());
row.put("auctionerId", ad.getAuctionerId());
row.put("debtId", ad.getId());
row.put("debtStatus", ad.getDebtStatus());
}
investIdList.add(investId);
String rowKey = currentUser +String.valueOf(investId);
List<Integer> rowIdx = rowMap.get(rowKey);
if(rowIdx == null){
rowIdx = new ArrayList<Integer>();
rowMap.put(rowKey, rowIdx);
}
rowIdx.add(i);
}
// end 封装处理翻页查询的结果 ,处理hessian 不支持的数据类型
List<Map<String,Object>> investAmountList = investRepaymentComponent.getInvestSuccessAmount(investIdList);
for(Map<String,Object> map : investAmountList){
Long investId = (Long)map.get("invest_id");
double recivedPrincipal = map.get("recivedPrincipal") == null ? 0 :((BigDecimal)map.get("recivedPrincipal")).doubleValue();
double hasPI = map.get("hasPI") == null ? 0 :((BigDecimal)map.get("hasPI")).doubleValue();
double notPI = map.get("notPI") == null ? 0 :((BigDecimal)map.get("notPI")).doubleValue();
double whbj = map.get("whbj") == null ? 0 :((BigDecimal)map.get("whbj")).doubleValue();
double blanceP = map.get("blanceP") == null ? 0 :((BigDecimal)map.get("blanceP")).doubleValue();
Long investor = (Long)map.get("investor");
/**
* 如果转让了,投资人可能不是当前用户
*/
List<Integer> rowIdxList = rowMap.get(String.valueOf(investor)+String.valueOf(investId));
if(rowIdxList != null){
for(int idx : rowIdxList){
Map<String,Object>row = investList.get(idx);
row.put("recivedPrincipal", CalculateUtils.round(recivedPrincipal));
row.put("hasPI", CalculateUtils.round(hasPI));
row.put("notPI", CalculateUtils.round(notPI));
row.put("whbj", CalculateUtils.round(whbj));
row.put("blanceP", CalculateUtils.round(blanceP));
}
}
}
page.setPage(investList);
return page;
}
/* (no-Javadoc)
* <p>Title: selectDebtSuccessRecordPage</p>
* <p>Description: </p>
* @param parameterMap
* @param page
* @return
* @see com.hehenian.biz.common.trade.IInvestService#selectDebtSuccessRecordPage(java.util.Map, com.hehenian.biz.common.base.dataobject.PageDo)
*/
@Override
public PageDo selectDebtSuccessRecordPage(Map<String, Object> parameterMap, PageDo page) {
parameterMap.put(Constants.MYBATIS_PAGE, page);
List<Map<String,Object>> debttList = investComponent.selectDebtSuccessRecordPage(parameterMap);
return page;
}
/* (no-Javadoc)
* <p>Title: getInvestSuccessAmountByUserId</p>
* <p>Description: </p>
* @param id
* @return
* @see com.hehenian.biz.common.trade.IInvestService#getInvestSuccessAmountByUserId(java.lang.Long)
*/
@Override
public Map<String, String> getInvestSuccessAmountByUserId(Long id) {
Map<String, Object> tmpMap = investRepaymentComponent.getInvestSuccessAmountByUserId(id);
//处理hessian bigdecimal 传不了
if(null == tmpMap){
return Collections.EMPTY_MAP;
}
Map<String, String> newMap = new HashMap<String,String>();
BigDecimal realAmount= tmpMap.get("realAmount") == null ? BigDecimal.ZERO:(BigDecimal) tmpMap.get("realAmount") ;
BigDecimal shouldGetAmount= tmpMap.get("shouldGetAmount") == null ? BigDecimal.ZERO:(BigDecimal) tmpMap.get("shouldGetAmount") ;
BigDecimal hasGetAmount= tmpMap.get("hasGetAmount") == null ? BigDecimal.ZERO:(BigDecimal) tmpMap.get("hasGetAmount") ;
newMap.put("realAmount", realAmount.toString());
newMap.put("shouldGetAmount", shouldGetAmount.toString());
newMap.put("hasGetAmount", hasGetAmount.toString());
newMap.put("noGetAmount",CalculateUtils.round(shouldGetAmount.doubleValue()-hasGetAmount.doubleValue()));
return newMap;
}
/**
* 查询用户投资的次数
* @param userId
* @return
*/
public long hasInvest(long userId){
return investComponent.hasInvest(userId);
}
public List<Map<String, Object>> getInvestDataForCSH(Long userId, Integer orderNo, Date beginDate, Date endDate) {
StringBuilder sb = new StringBuilder();
sb.append("select tft.trade_id orderNo,tft.trade_time transDate,concat(tft.trade_amount,'') transAmount")
.append(",tft.user_id userId,concat(tft.rate,'') yearRate,pr.period term,cli.cname,cli.busGroupName groupName ")
.append("from td_fund_trade tft inner join td_product_rate pr on tft.rate_id=pr.product_rate_id ")
.append("left join t_colourlife_info cli on tft.user_id=cli.userId where ");
List<Map<String, Object>> resultList = null;
try {
if(orderNo == null || orderNo <=0) {
sb.append("tft.user_id=? and tft.trade_time>=? and tft.trade_time<=? + interval 1 day;");
resultList = sp2pJdbcTemplate.queryForList(sb.toString(), userId, beginDate, endDate);
} else {
sb.append("tft.trade_id=?;");
resultList =sp2pJdbcTemplate.queryForList(sb.toString(), orderNo);
}
return resultList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public int saveAgreement(FundTradeAgreement fta, AgreementEnum agreementType, Map agreementData) {
if(fta == null || fta.getUserId() == null) {
return -1;
}
StringBuilder sb = new StringBuilder();
sb.append("insert into td_fund_trade_agreement values (?,?,?,?,?,?);");
int ret = sp2pJdbcTemplate.update(sb.toString(), fta.getId(), fta.getUserId(), fta.getAgreementType(), fta.getTradeId(), fta.getAgreementFileName(), fta.getCreateTime());
if(ret > 0) {
FileClient fc = new FileClient();
fc.saveAgreement(fta.getUserId(), fta.getAgreementFileName(), agreementType, agreementData);
return 1;
}
return -1;
}
}