Commit a2458c50 by 王德峰

bb 项目初始化

清理部分
parent 301a6da8
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.api.analyse;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.crypto.SecureUtil;
import com.abssqr.plat.biz.support.ServiceSupport;
import com.abssqr.plat.common.dal.mysql.auto.paging.PlanListPage;
import com.abssqr.plat.common.facade.constants.AbssqrConstants;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.ReportTypeEnum;
import com.abssqr.plat.common.facade.model.analyse.PlanFundFile;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.report.PlanReport;
import com.abssqr.plat.common.facade.model.report.PlanReportItem;
import com.abssqr.plat.common.facade.model.report.ReportField;
import com.abssqr.plat.common.facade.model.report.wk.WkAstReportFields;
import com.abssqr.plat.common.facade.param.analyse.AnalyseBaseParam;
import com.abssqr.plat.common.facade.param.analyse.CalcFundParam;
import com.abssqr.plat.common.facade.param.analyse.FundPlanFileQprParam;
import com.abssqr.plat.common.facade.param.analyse.FundPlanFileQryParam;
import com.abssqr.plat.common.facade.param.plan.PlanPageQryParam;
import com.abssqr.plat.common.facade.result.BasePage;
import com.abssqr.plat.common.facade.result.analyse.AnalysePlanItemVO;
import com.abssqr.plat.common.facade.result.analyse.CalcFundDefaultParam;
import com.abssqr.plat.common.facade.result.analyse.CalcFundResultVO;
import com.abssqr.plat.common.facade.result.analyse.PlanAnalyseVO;
import com.abssqr.plat.common.facade.service.analyse.AnalyseFundSpvService;
import com.abssqr.plat.common.facade.utils.CalcUtil;
import com.abssqr.plat.common.facade.validation.Valid;
import com.abssqr.plat.common.integration.wk.domain.config.WkSftpConfig;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.analyse.PlanFundFileRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.utils.FileType;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.abssqr.plat.core.service.report.AnalyseSpvReportManager;
import com.abssqr.plat.core.service.util.AnalyseReportUtil;
import com.general.system.common.model.Money;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.SystemDateUtil;
import com.general.system.common.util.VarChecker;
import com.general.system.facade.current.IdentityUtil;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 项目分析资金计划 管理
* @author hanfei
* @version $Id: AnalyseFundSpvServiceImpl.java, v 0.1 2019-09-19 4:23 PM hanfei Exp $
*/
@Service
public class AnalyseFundSpvServiceImpl extends ServiceSupport implements AnalyseFundSpvService {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final List<ReportField> amtFields = Lists.newArrayList(
WkAstReportFields.WK017,
WkAstReportFields.WK018,
WkAstReportFields.WK019,
WkAstReportFields.WK001
);
// 资产 本金 利息 罚息
private static final List<ReportField> astScale = Lists.newArrayList(
WkAstReportFields.WK017,
WkAstReportFields.WK018,
WkAstReportFields.WK019);
@Autowired
private PlanManager planManager;
@Autowired
private PlanFundFileRepo planFundFileRepo;
@Autowired
private PlanAllocRepo planAllocRepo;
@Autowired
private AnalyseSpvReportManager analyseSpvReportManager;
@Autowired
private WkSftpConfig wkSftpConfig;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@Autowired
private PlanReportRepo planReportRepo;
/**
* 获取资金计划文件
* @param param
* @return
*/
@Override
public PlanFundFile getFundPlanFile(FundPlanFileQryParam param) {
return super.doQry(param, () -> {
VarChecker.checkNotNull(param.getFileId(), "文件变号不能为空");
PlanFundFile file = planFundFileRepo.getByFileId(param.getFileId());
// 根据文件路径 获取文件
FastByteArrayOutputStream stream = wkSftpConfig.downloadSftp(file.getFilePath());
if (stream == null) {
throw new AbssqrBizException("未找到文件", CommonErrorCodeEnum.SFTP_ERROR);
}
file.setFileOutStream(stream);
return file;
});
}
/**
* 获取资金计划文件页面数据
* @return
*/
@Override
public BasePage queryFundFile(AnalyseBaseParam param) {
return super.doQry(param, () -> {
VarChecker.checkNotEmpty(param.getPlanNo(), "项目编号不能为空");
// 查询计划
analyseSpvReportManager.checkGetPlan(param.getPlanNo());
PlanFundFile file = planFundFileRepo.queryFileInfo(param.getPlanNo());
BasePage page = new BasePage();
page.setDatas(Lists.newArrayList(file));
page.setTotal(1);
return page;
});
}
/**
* 上传资金计划文件
* @param param
* @return
*/
@Override
public String uploadPlanFile(FundPlanFileQprParam param) {
return super.doOpr(param, () -> {
VarChecker.checkNotEmpty(param.getPlanNo(), "项目编号不能为空");
VarChecker.checkNotNull(param.getFile(), "上传文件不能为空");
// 查询计划
PlanBase planBase = analyseSpvReportManager.checkGetPlan(param.getPlanNo());
// 组装文件信息
PlanFundFile fundFile = new PlanFundFile();
fundFile.setFileName(param.getFile().getOriginalFilename());
fundFile.setFileId(SequenceUtil.genFakeSeqNo());
String suffix = FileType.getSuffixByFilename(fundFile.getFileName());
// 随机文件名
String pathFileName = fundFile.getFileId().concat(suffix);
fundFile.setFilePath(wkSftpConfig.getPath().concat(File.separator).concat(pathFileName));
fundFile.setUploadDate(SystemDateUtil.getSystemDate());
fundFile.setUploadType(wkSftpConfig.getType());
fundFile.setPlanNo(planBase.getPlanNo());
try {
String fileMd5 = SecureUtil.md5(param.getFile().getInputStream()).toUpperCase();
fundFile.setFileMd5(fileMd5);
// 处理上传文件
wkSftpConfig.uploadSftp(param.getFile().getInputStream(), pathFileName, wkSftpConfig.getPath());
} catch (IOException e) {
throw new AbssqrBizException("处理上传文件时异常", e);
}
// 保存数据
planFundFileRepo.create(fundFile);
return fundFile.getFileId();
});
}
/**
* 短期资金需求计算器 默认信息
* @param param
* @return
*/
@Override
public CalcFundDefaultParam fundCalcView(AnalyseBaseParam param) {
return super.doQry(param, () -> {
VarChecker.checkNotEmpty(param.getPlanNo(), "项目编号不能为空");
String planNo = param.getPlanNo();
// 转让系统会计日
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
// 查询计划
PlanBase planBase = analyseSpvReportManager.checkGetFullPlan(planNo);
// 最后一日报表
PlanReport planReport = planReportRepo.getLatestReport(param.getPlanNo(), ReportTypeEnum.RPT001);
// D-1日
Date lastDate = AnalyseReportUtil.getStatDate(trfDate, null, planReport);
// D-30日
final Date last30Date = DateUtil.offsetDay(lastDate, AbssqrConstants.AVG_SPARE);
// 统计 闲置资金余额
Map<String, PlanReportItem> itemBalMap = analyseSpvReportManager.querySpvStatPlanDayItem(
lastDate, planBase.getPlanNo(), CollectionUtil.newArrayList(WkAstReportFields.WK001), true);
VarChecker.checkNotNull(itemBalMap, "[{0}-{1}]计划最近报表[{2}]未生成!", planBase.getPlanNo(), planBase.getPlanName(), DateTimeUtil.formatY_M_D(lastDate));
// 资金余额
Money ableBal = AnalyseReportUtil.getItemMoney(itemBalMap, WkAstReportFields.WK001);
// 计算时间间隔,可能没有够时长的报表数据,last30Date 会根据数据日期进行变化
AtomicInteger spare = new AtomicInteger(30);
// 统计30日放款额
Map<String, PlanReportItem> itemGrantMap = analyseSpvReportManager.querySpvStatPlanSectionItem(
last30Date, lastDate, planBase.getPlanNo(), CollectionUtil.newArrayList(WkAstReportFields.WK111), false, spare);
// 日均放款额
Money grantAmt = new Money();
if (spare.get() > 0) {
// 放款金额 spare 天平均
grantAmt = AnalyseReportUtil.getItemMoney(itemGrantMap, WkAstReportFields.WK111)
.divide(new BigDecimal(spare.get()), AbssqrConstants.DECIMAL_ROUNDING_MODE);
}
CalcFundDefaultParam defaultParam = new CalcFundDefaultParam();
defaultParam.setPlanNo(planNo);
// 回款率 D-30日
defaultParam.setRepayRate(analyseSpvReportManager.getRepayRate(last30Date, lastDate, planNo));
// 可用余额
defaultParam.setAbleBal(ableBal);
// 放款金额
defaultParam.setGrantAmt(grantAmt);
return defaultParam;
});
}
/**
* 短期资金需求计算器
* @param param
* @return
*/
@Override
public CalcFundResultVO fundCalc(@Valid CalcFundParam param) {
return super.doQry(param, () -> {
VarChecker.checkNotNull(param.getPlanNo(), "项目计划编号不能为空");
VarChecker.checkNotNull(param.getAccountDate(), "募集日需不能为空");
VarChecker.checkNotNull(param.getGrantAmtDesc(), "日均放款额不能为空");
VarChecker.checkNotNull(param.getAbleBal(), "可用余额不能为空");
VarChecker.checkNotNull(param.getRepayRate(), "回款率不能为空");
// 转让系统会计日
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
// 募集日
Date raiseDate = DateUtil.parseDate(param.getAccountDate());
int spare = Long.valueOf(DateUtil.betweenDay(trfDate.getStandardDate(), raiseDate, true) + 1).intValue();
VarChecker.checkArgument(spare > 0, "募集日需要大于当前会计日");
// 查询校验计划
analyseSpvReportManager.checkGetPlan(param.getPlanNo());
// 获取 期间兑付金额
// Money allocAmt = planAllocRepo.queryStatAllocAmtByPlanNoAndPayDate(calcDate, raiseDate, param.getPlanNo());
// 总资产金额 查询当前资产情况
// Money astScale = loanInstalRepository.getPlanAstScale(param.getPlanNo());
// astScale = Money.createWithCent(100000000000L);
// 最后一日报表
PlanReport planReport = planReportRepo.getLatestReport(param.getPlanNo(), ReportTypeEnum.RPT001);
// 统计总贷款本金余额
Map<String, PlanReportItem> itemGrantMap = analyseSpvReportManager.querySpvStatPlanDayItem(
AnalyseReportUtil.getStatDate(trfDate,null, planReport), param.getPlanNo(),
CollectionUtil.newArrayList(WkAstReportFields.WK017), true);
Money grantAmt = new Money(param.getGrantAmtDesc().multiply(new BigDecimal(10000)));
// 当前资金余额 + 募集资金金额
Money bal = new Money(param.getAbleBal().multiply(new BigDecimal(10000)))
.addTo(new Money(param.getScaleAmtDesc().multiply(new BigDecimal(10000))));
BigDecimal repayRate = CalcUtil.calcRealRate(param.getRepayRate());
// 当前资产还款总计(当前资产 * 日还款率 * 天数)
Money scaleFlowIn = AnalyseReportUtil.getItemMoney(itemGrantMap, WkAstReportFields.WK017)
.multiply(repayRate).multiply(spare);
// Money grantFlowIn = calcRepayArray(new Money(param.getGrantAmtDesc()), repayRate, result.getSpareDays());
// 未来资产还款累计连加和(∑天数.日均放款*日还款率)
double radix = NumberUtil.div((spare+1) * spare, 2);
Money grantFlowIn = grantAmt.multiply(repayRate).multiply(radix);
// 预计流出金额 = 日均放款预计 * 距离募集剩余天数 + 期间兑付额
Money flowOut = grantAmt.multiply(spare);
CalcFundResultVO result = new CalcFundResultVO();
result.setPlanNo(param.getPlanNo());
// 剩余天数
result.setSpareDays(spare);
// 预计还款流入金额 = 当前资产还款总计(当前资产 * 日还款率 * 天数) + 未来资产还款累计连加和(∑天数.日均放款*日还款率)
result.setFlowInAmt(scaleFlowIn.add(grantFlowIn));
// 预计募集日账户余额 = 当前资金余额 + 募集资金金额 + 预计期间还款流入 - 预计流出金额(合计放款 + 期间兑付额)
result.setPlanAbleBal(bal.addTo(result.getFlowInAmt()).subtractFrom(flowOut));
return result;
});
}
/**
* 查询项目计划分析列表
* @return
*/
@Override
public BasePage queryAnalyseSpvPlan(PlanPageQryParam param) {
return super.doQry(param, () -> {
BasePage page = new BasePage();
param.setPlanType(PlanTypeEnum.SPV.getCode());
PlanListPage planList = planManager.getPlanList(param,
CollectionUtil.newArrayList(PlanStatusEnum.ONGOING.getCode(), PlanStatusEnum.COMPLETED.getCode()), IdentityUtil.getUserCode());
if (ToolUtil.isEmpty(planList.getDatas())) {
return page;
}
// 闲置资金余额
List<ReportField> ableBal = Lists.newArrayList(WkAstReportFields.WK001);
List<AnalysePlanItemVO> items = new ArrayList<>();
planList.getDatas().forEach(one -> {
PlanBase planBase = planManager.getPlanFullByNo(one.getPlanNo());
AnalysePlanItemVO item = new AnalysePlanItemVO();
item.setPlanNo(planBase.getPlanNo());
item.setPlanName(planBase.getPlanName());
PlanReport planReport = planReportRepo.getLatestReport(planBase.getPlanNo(), ReportTypeEnum.RPT001);
if(planReport!=null) {
Date lastDate = planReport.getRptDate().getAccountDate();
// D-30日
final Date last30Date = DateUtil.offsetDay(lastDate, AbssqrConstants.AVG_SPARE);
// 查询资金计划文件
PlanFundFile file = planFundFileRepo.queryFileInfo(planBase.getPlanNo());
// 查询计划对应统计项数据
Map<String, PlanReportItem> itemMap =
analyseSpvReportManager.querySpvStatPlanDayItem(lastDate, planBase.getPlanNo(), amtFields, true);
// 本金规模
item.setPrinScale(AnalyseReportUtil.getItemMoney(itemMap, WkAstReportFields.WK017));
// 资产规模
item.setAstScale(AnalyseReportUtil.getItemMoney(itemMap, astScale));
// 可用余额
item.setAbleBal(AnalyseReportUtil.getItemMoney(itemMap, ableBal));
// 获取 逾期率 闲置率 回收率 早偿率
item.setOvdRate(analyseSpvReportManager.getOvdRate(last30Date, lastDate, planBase.getPlanNo()));
item.setIdleRate(analyseSpvReportManager.getAvgIdleRateRate(lastDate, planBase));
item.setRepayRate(analyseSpvReportManager.getRepayRate(last30Date, lastDate, planBase.getPlanNo()));
item.setPreRepayRate(analyseSpvReportManager.getPreRepayRate(last30Date, lastDate, planBase.getPlanNo()));
item.setFundPlanDate(file == null ? "--" : DateUtil.formatDate(file.getUploadDate()));
}
items.add(item);
});
page.setDatas(items);
page.setTotal(planList.getTotal());
page.setCurrPageNo(planList.getCurrPageNo());
return page;
});
}
/**
* 查询计划概要信息
* @param param
* @return
*/
@Override
public PlanAnalyseVO getAnalyseSpvPlan(AnalyseBaseParam param) {
return super.doQry(param, () -> {
VarChecker.checkNotEmpty(param.getPlanNo(), "项目编号不能为空");
// 转让系统会计日
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
// 查询计划
PlanBase planBase = analyseSpvReportManager.checkGetPlan(param.getPlanNo());
// 最后一日报表
PlanReport planReport = planReportRepo.getLatestReport(param.getPlanNo(), ReportTypeEnum.RPT001);
// 统计日 默认D-1日
Date accDate = AnalyseReportUtil.getStatDate(trfDate, param.getAccountDate(), planReport);
PlanAnalyseVO analyseVO = new PlanAnalyseVO();
analyseVO.setPlanNo(planBase.getPlanNo());
analyseVO.setPlanName(planBase.getPlanName());
// 查询计划本金规模 "WK017", "总贷款本金余额"
Map<String, PlanReportItem> itemMap = analyseSpvReportManager.querySpvStatPlanDayItem(
accDate, param.getPlanNo(), CollectionUtil.newArrayList(WkAstReportFields.WK017), true);
analyseVO.setPrinScale(AnalyseReportUtil.getItemMoney(itemMap, WkAstReportFields.WK017));
analyseVO.setAccountDate(DateUtil.formatDate(accDate));
return analyseVO;
});
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.api.plan;
import com.abssqr.plat.biz.shared.handler.PlanAllocHandler;
import com.abssqr.plat.biz.support.ServiceSupport;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanAllocStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.plan.PlanAlloc;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocHandleParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocPayParam;
import com.abssqr.plat.common.facade.result.plan.PlanAllocPayInfoVO;
import com.abssqr.plat.common.facade.service.plan.PlanAllocPayService;
import com.abssqr.plat.common.facade.validation.Valid;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.core.service.acct.AcctManager;
import com.general.system.common.util.VarChecker;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 分配支付或入账
*
* @author hanfei
* @version $Id: PlanAllocPayServiceImpl.java, v 0.1 2019-07-09 4:48 PM hanfei Exp $
*/
@Service
public class PlanAllocPayServiceImpl extends ServiceSupport implements PlanAllocPayService {
@Autowired
private PlanAllocRepo planAllocRepo;
@Autowired
private PlanAllocHandler planAllocHandler;
@Autowired
private PlanRepo planRepo;
@Autowired
private AcctManager acctManager;
/**
* 分配支付或人工分配入账
*
* @param param
*/
@Override
public void allocPay(@Valid PlanAllocPayParam param) {
super.doOpr(param, () -> {
// 获取对应分配计划进行支付
PlanAlloc alloc = planAllocRepo.getPlanAllocDetail(param.getAllocNo());
if (alloc.getStatus() == PlanAllocStatusEnum.ASSIGNED) {
return null;
}
PlanAllocHandleParam handleParam = new PlanAllocHandleParam();
handleParam.setAlloc(alloc);
handleParam.setOutTransNo(param.getOutTransNo());
handleParam.setOffLine(param.getOffLine());
// 判断线上线下操作
if (param.getOffLine()) {
// 线下支付 创建支付单,同时进行入账等后续操作
planAllocHandler.execute(handleParam);
} else {
// 在线支付,只创建支付单
planAllocHandler.handle(handleParam);
}
return null;
});
}
/**
* 查询分配详情
*
* @param param
* @return
*/
@Override
public PlanAllocPayInfoVO allocInfo(@Valid PlanAllocPayParam param) {
return super.doQry(param, () -> {
// 获取对应分配计划进行支付
PlanAlloc alloc = planAllocRepo.getPlanAllocDetail(param.getAllocNo());
// 获取对应计划
PlanBase plan = planRepo.getPlanByNo(alloc.getPlanNo());
//回款账户状态
AccountAttributeEnum sourceAcct = PlanTypeEnum.SPV == alloc.getPlanType() ?
AccountAttributeEnum.RECV : AccountAttributeEnum.NORMAL;
// 获取账户信息
List<Account> accounts = acctManager.getAllAcctByPlanNo(alloc.getPlanNo(),
Lists.newArrayList(AccountTypeEnum.BANK, AccountTypeEnum.PLAT_VIRTUAL));
VarChecker.checkNotEmpty(accounts, "计划[{0}]找不到对应的账户信息", alloc.getPlanNo());
// 组装模型
PlanAllocPayInfoVO infoVO = new PlanAllocPayInfoVO();
infoVO.setPlanNo(alloc.getPlanNo());
infoVO.setPlanName(plan.getPlanName());
infoVO.setPayAmt(alloc.getTotalConfirmAllocAmt());
for (Account account : accounts) {
// 源账户 为 银行一般业务户
if (account.getActAttr() == sourceAcct
&& account.getActType() == AccountTypeEnum.BANK) {
infoVO.setSourceAcct(infoVO.installAccount(account));
}
// 目标账户为 银行 托管户
if (account.getActAttr() == AccountAttributeEnum.HOSTED
&& account.getActType() == AccountTypeEnum.BANK) {
infoVO.setTargetAcct(infoVO.installAccount(account));
}
}
return infoVO;
});
}
}
......@@ -8,7 +8,6 @@ import java.util.List;
import java.util.stream.Collectors;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.planAstStat.PlanAstStatTaskStarter;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.domain.task.CommonTask;
......
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.dispatcher.planAstStat;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutorTemp;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.common.dal.mysql.auto.dao.PlanAstStatTaskDAO;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.core.service.system.TimeStampUtil;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.SystemDateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 计划统计任务
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.task.task: PlanAstStatTaskExecutor.java, v 0.1 2018-01-08 02:15 hongwei.wang Exp $
*/
@Component
public class PlanAstStatTaskExecutor extends DispatcherExecutorTemp<PlanAstStatTask> {
private final static Logger logger = LoggerFactory.getLogger(
PlanAstStatTaskExecutor.class);
@Autowired
private PlanAstClearingStatHandler planAstClearingStatHandler;
@Autowired
private PlanAstStatTaskDAO planAstStatTaskDAO;
@Override
protected PlanAstStatTask doExecute(PlanAstStatTask node) {
String execTms = TimeStampUtil.getCurrentBufferedTimestamp();
return planAstClearingStatHandler.execute(node, execTms);
}
@Override
protected PlanAstStatTask markSuccess(PlanAstStatTask node) {
// 在内部处理,不单独标记
return node;
}
@Override
protected PlanAstStatTask markFail(PlanAstStatTask node, String failMessage) {
// 因异常引起的重试
Date nextTime = DateTimeUtil.addSecond(SystemDateUtil.getSystemDate(), 30);
node.setStatus(OrgAstStatStatusEnum.ACTIVE);
planAstStatTaskDAO.updateTaskExep(nextTime, node.getPlanNo());
return node;
}
@Override
protected PlanAstStatTask markException(PlanAstStatTask node, String failMessage) {
Date nextTime = DateTimeUtil.addSecond(SystemDateUtil.getSystemDate(), 30);
node.setStatus(OrgAstStatStatusEnum.ACTIVE);
planAstStatTaskDAO.updateTaskExep(nextTime, node.getPlanNo());
return node;
}
@Override
protected String getName() {
return "PlanAstStatTaskExecutor";
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.dispatcher.planAstStat;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.job.JobControlRepository;
import com.abssqr.plat.core.service.host.HostManager;
import com.general.system.common.util.SystemDateUtil;
import com.general.system.common.util.VarChecker;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
import java.util.stream.Collectors;
/**
* 资产转让
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.task.task: PlanAstStatTaskLoader.java, v 0.1 2018-01-08 00:59 hongwei.wang Exp $
*/
@Component
public class PlanAstStatTaskLoader implements DispatcherLoader<PlanAstStatTask> {
@Autowired
private PlanAstStatTaskRepo planAstStatTaskRepo;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private HostManager hostManager;
@Autowired
private JobControlRepository jobControlRepository;
/**
* 装载待分发节点
*
* @param size
* @return
*/
@Override
public List<PlanAstStatTask> loadToDoNodes(int size) {
return transactionTemplate.execute(transactionStatus -> {
// 太多乐观锁冲突报错了,还是加个锁吧
jobControlRepository.lockByJobName(PlanAstStatTaskStarter.JOB_NAME);
List<PlanAstStatTask> tasks = planAstStatTaskRepo.getToDo(SystemDateUtil.getSystemDate(), size);
if (CollectionUtils.isEmpty(tasks)) {
return Lists.newArrayList();
}
List<String> planNos = tasks.stream().map(PlanAstStatTask::getPlanNo).collect(Collectors.toList());
int count = planAstStatTaskRepo.updateTaskExec(SystemDateUtil.getSystemDate(),
hostManager.getHostInfo().getHostName(),
planNos);
VarChecker.checkEquals(count, planNos.size(), "[TaskLoader.loadToDoNodes]更新任务数跟期望数不一致,实际更新:{0},期望更新:{1} - {2}",
count,
planNos.size(),
planNos);
return tasks;
});
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.dispatcher.planAstStat;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherStarter;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.core.service.host.HostManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.task.task: PlanAstStatTaskStarter.java, v 0.1 2018-01-08 02:42 hongwei
* .wang Exp $
*/
@Component
public class PlanAstStatTaskStarter extends DispatcherStarter<PlanAstStatTask> {
public static String JOB_NAME = "PlanAstStatTaskDispatcher";
@Autowired
private PlanAstStatTaskExecutor planAstStatTaskExecutor;
@Autowired
private PlanAstStatTaskLoader planAstStatTaskLoader;
@Autowired
private HostManager hostManager;
@Autowired
private PlanAstStatTaskRepo planAstStatTaskRepo;
private int coreSize = 2;
private int maxSize = 3;
private int hungrySize = 2;
@Override
protected void recovery() {
planAstStatTaskRepo.updateHangTasksByIp(hostManager.getHostInfo().getHostName());
}
@Override
public String getName() {
return JOB_NAME;
}
@Override
protected int getCoreSize() {
return coreSize;
}
@Override
protected int getMaxSize() {
return maxSize;
}
@Override
protected int getQueueSize() {
return 4;
}
@Override
protected int getHungrySize() {
return hungrySize;
}
@Override
protected DispatcherLoader<PlanAstStatTask> getLoader() {
return planAstStatTaskLoader;
}
@Override
protected DispatcherExecutor<PlanAstStatTask> getExecutor() {
return planAstStatTaskExecutor;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.dispatcher.wkPlanReport;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutorTemp;
import com.abssqr.plat.biz.shared.handler.WkPlanReportHandler;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.repo.task.CommonTaskRepository;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import com.general.system.common.util.SystemDateUtil;
import org.apache.commons.lang3.tuple.MutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 计划统计任务
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.task.task: PlanAstStatTaskExecutor.java, v 0.1 2018-01-08 02:15 hongwei.wang Exp $
*/
@Component
public class PlanReportTaskExecutor extends DispatcherExecutorTemp<CommonTask> {
private final static Logger LOGGER = LoggerFactory.getLogger(
PlanReportTaskExecutor.class);
@Autowired
private WkPlanReportHandler wkPlanReportHandler;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@Autowired
private CommonTaskRepository commonTaskRepository;
@Autowired
private PlanManager planManager;
@Override
public CommonTask doExecute(CommonTask node) {
LogUtil.info(LOGGER, "执行计划报表任务[{0}]", node);
PlanBase planBase = planManager.getPlanFullByNo(node.getContext());
Day accountDate = orgAcctDayComponent.getAstAcctDay(orgAcctDayComponent.getOrgCode(planBase));
MutablePair<Boolean, String> rptResult = wkPlanReportHandler.execute(accountDate.getStandardDate(), planBase);
if (rptResult.getLeft()) {
return markSuccess(node);
} else {
return markFail(node, MessageUtil.formatMsg("[{0}]项目[{1}]报表执行暂时退出:{2}",
planBase.getPlanNo(), accountDate.getDayString(), rptResult.getRight()));
}
}
@Override
protected CommonTask markSuccess(CommonTask node) {
commonTaskRepository.updateTaskStatus(node.getId(), TaskStatusEnum.SUCCESS, TaskStatusEnum.EXECUTING, "");
node.setTaskStatus(TaskStatusEnum.SUCCESS);
return node;
}
@Override
protected CommonTask markFail(CommonTask node, String failMessage) {
// 因异常引起的重试
Date nextTime = DateTimeUtil.addSecond(SystemDateUtil.getSystemDate(), 60);
String msg = failMessage.length()>2000?failMessage.substring(0,2000):failMessage;
commonTaskRepository.updateTaskExep(nextTime, node.getId(), msg);
return node;
}
@Override
protected CommonTask markException(CommonTask node, String failMessage) {
return markFail(node, failMessage);
}
@Override
protected String getName() {
return "PlanReportTaskExecutor";
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.dispatcher.wkPlanReport;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.enums.ReportTypeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.report.DailyReportDateField;
import com.abssqr.plat.common.facade.model.report.PlanReport;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.repo.job.JobControlRepository;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.model.repo.task.CommonTaskRepository;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.host.HostManager;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.SystemDateUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 计划报表异步处理
*
* @author zhenxuan.luo
* @version com.abssqr.piz.shared.task.task: PlanAstStatTaskLoader.java, v 0.1 2018-01-08 00:59 hongwei.wang Exp $
*/
@Component
public class PlanReportTaskLoader implements DispatcherLoader<CommonTask> {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private HostManager hostManager;
@Autowired
private JobControlRepository jobControlRepository;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanReportRepo planReportRepo;
@Autowired
private CommonTaskRepository commonTaskRepository;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 装载待分发节点
*
* @param size
* @return
*/
@Override
public List<CommonTask> loadToDoNodes(int size) {
List<CommonTask> tasks = Lists.newArrayList();
List<CommonTask> existsTask = commonTaskRepository
.selectUnifinishTaskByType(CommonTaskTypeEnum.PLAN_REPORT);
Map<String, CommonTask> taskMap = existsTask.stream()
.collect(Collectors.toMap(CommonTask::getContext, item -> item));
List<PlanBase> plans = planRepo.getPlansByStatus(null, PlanStatusEnum.ONGOING);
return transactionTemplate.execute(transactionStatus -> {
// 太多乐观锁冲突报错了,还是加个锁吧
jobControlRepository.lockByJobName(PlanReportTaskStarter.JOB_NAME);
for (PlanBase planBase : plans) {
CommonTask commonTask = taskMap.get(planBase.getPlanNo());
// 获取对应机构会计日
Day accountDate = orgAcctDayComponent.getAstAcctDay(orgAcctDayComponent.getOrgCode(planBase));
if (null == commonTask) {
PlanReport planReport = planReportRepo.getLatestReport(planBase.getPlanNo(), ReportTypeEnum.RPT001);
DailyReportDateField reportDateField;
if (null != planReport) {
// 只判断日报,月报没有判断,当天月报失败需要第二天才能执行 或手动触发
reportDateField = (DailyReportDateField) planReport.getRptDate();
if (DateTimeUtil.calcDayDiff(reportDateField.getAccountDate(), accountDate.getStandardDate()) >= 0) {
continue;
}
}
commonTask = new CommonTask();
commonTask.setBizNo(SequenceUtil.genWkSeqNo());
commonTask.setTaskType(CommonTaskTypeEnum.PLAN_REPORT);
commonTask.setContext(planBase.getPlanNo());
commonTask.setEnv(null);
commonTask.setMemo("");
commonTask.setTaskStatus(TaskStatusEnum.INIT);
commonTask.setNextExecTime(SystemDateUtil.getSystemDate());
commonTask.setExecTimes(0L);
commonTaskRepository.create(commonTask);
} else {
if (commonTask.getTaskStatus() != TaskStatusEnum.INIT) {
continue;
} else if (SystemDateUtil.getSystemDate().compareTo(commonTask.getNextExecTime()) < 0) {
continue;
}
}
tasks.add(commonTask);
if (tasks.size() >= size) {
break;
}
}
if (CollectionUtils.isNotEmpty(tasks)) {
commonTaskRepository
.updateTaskExec(SystemDateUtil.getSystemDate(), hostManager.getHostInfo().getHostName(),
tasks);
}
return tasks;
});
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.dispatcher.wkPlanReport;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.DispatcherStarter;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.repo.task.CommonTaskRepository;
import com.abssqr.plat.core.service.host.HostManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.task.task: PlanAstStatTaskStarter.java, v 0.1 2018-01-08 02:42 hongwei
* .wang Exp $
*/
@Component
public class PlanReportTaskStarter extends DispatcherStarter<CommonTask> {
public static String JOB_NAME = "PlanReportTaskDispatcher";
@Autowired
private PlanReportTaskExecutor planReportTaskExecutor;
@Autowired
private PlanReportTaskLoader planReportTaskLoader;
@Autowired
private HostManager hostManager;
@Autowired
private CommonTaskRepository commonTaskRepository;
private int coreSize = 2;
private int maxSize = 2;
private int hungrySize = 1;
private int queueSize = 2;
@Override
protected void recovery() {
commonTaskRepository.updateHangTasksByIp(hostManager.getHostInfo().getHostName());
}
@Override
public String getName() {
return JOB_NAME;
}
@Override
protected int getCoreSize() {
return coreSize;
}
@Override
protected int getMaxSize() {
return maxSize;
}
@Override
protected int getQueueSize() {
return queueSize;
}
@Override
protected int getHungrySize() {
return hungrySize;
}
@Override
protected DispatcherLoader<CommonTask> getLoader() {
return planReportTaskLoader;
}
@Override
protected DispatcherExecutor<CommonTask> getExecutor() {
return planReportTaskExecutor;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.handler;
import cn.hutool.json.JSONUtil;
import com.abssqr.plat.common.facade.enums.PlanAllocStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanAlloc;
import com.abssqr.plat.common.facade.model.plan.PlanAst;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocHandleParam;
import com.abssqr.plat.common.model.domain.plan.PlanAllocFrozen;
import com.abssqr.plat.common.model.domain.plan.PlanAstLog;
import com.abssqr.plat.common.model.enums.TraderTypeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanAllocFrozenRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.plan.PlanAllocManager;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.abssqr.plat.core.share.pay.PlanCapitalCreateRequest;
import com.abssqr.plat.core.share.pay.PlanCapitalFinishRequest;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.alibaba.fastjson.JSON;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import com.general.system.common.util.VarChecker;
import com.general.system.util.adapter.AbstractBaseActionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
/**
* 分配兑付
* 两个调用场景:
* 1. 审批通过后直接发起线上支付 : 调用 handle 方法, 然后获取到支付单结果后执行 allocTitleEntry
*
* 2. 审批通过后修改状态为待支付,有人工手工入账,此时没有支付操作 ,调用 execute 方法执行全部操作
*
* @author hanfei
* @version $Id: PlanAllocHandler.java, v 0.1 2019-07-06 11:46 AM hanfei Exp $
*/
@Component
public class PlanAllocHandler extends AbstractBaseActionHandler<PlanAllocHandleParam, PlanCapitalOrder> {
protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private PlanAllocManager planAllocManager;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private PlanAllocFrozenRepo planAllocFrozenRepo;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 分配支付的发起
* 1. 生成支付单
*
* -- 分配入账(可能存在两个调用来源:1. 审批通过后直接发起支付,2. 审批通过后修改状态为待支付,有人工手工入账,此时没有支付操作
* 2. 更新分配计划状态为已分配
* 3. 登记分配计划下,各分配事项对应科目的"付"发生额和流水
*/
@Override
public PlanCapitalOrder handle(PlanAllocHandleParam handleParam) {
// 获取转让会计日
Day accountDate = orgAcctDayComponent.getTrfAcctDay();
PlanAlloc alloc = handleParam.getAlloc();
// 对分配计划加锁
PlanAlloc lock = planAllocManager.lockByAllocNo(alloc.getAllocNo());
VarChecker.checkEquals(lock.getStatus(), PlanAllocStatusEnum.UNASSIGNE,
"计划[{0}]当前分配计划[{1}]不能进行分配,状态为[{2}]", alloc.getPlanNo(), alloc.getAllocNo(), alloc.getStatus());
// 分配兑付操作发起支付创建支付订单 明确时分配兑付类型
PlanCapitalTransTypeEnum transTypeEnum;
if (alloc.getPlanType() == PlanTypeEnum.SPV){
transTypeEnum = PlanCapitalTransTypeEnum.NT_DIST;
}else{
transTypeEnum = PlanCapitalTransTypeEnum.DIST;
}
PlanCapitalCreateRequest request = new PlanCapitalCreateRequest();
request.setAccountDate(accountDate.getStandardDate());
// 使用分配计划 编号作为业务编码
request.setBizNo(alloc.getAllocNo());
request.setPlanNo(alloc.getPlanNo());
// 目标机构 填入 计划编号
request.setTargetOrgCode(alloc.getPlanNo());
// 获取分配计划应兑付金额总和
request.setTransAmt(alloc.getTotalConfirmAllocAmt());
// 应付金额
request.setPayableAmt(alloc.getTotalConfirmAllocAmt());
// 交易类型
request.setTransType(transTypeEnum);
request.setMemo(MessageUtil.formatMsg("-日期[{2}]分配兑付", alloc.getPayDate()));
// 1 发起支付 创建支付订单
PlanCapitalOrder order = planCapitalOrderManager.createCapitalOrder(request);
LogUtil.info(LOGGER, "计划[{0}-{1}]创建支付交易单type[{2}]cntPty[{3}]amt[{4}]bizNo[{5}]",
order.getPlanNo(), order.getAccountDate(), transTypeEnum, order.getCntPtyCode(), order.getTransAmt(), order.getBizNo());
// 2 记录清算在资产水位表中 增加支付在途金额 并将冻结金额解冻
planAstManager.changePlanAst(accountDate.getStandardDate(), alloc.getPlanNo(), (planAst,planAstLogList) -> {
// 2.1 分配兑付需要进行解冻记录冻结金额解冻变化
this.unFrozen(planAstLogList, accountDate.getStandardDate(), planAst, order);
// 2.2 更新计划资产水位表,追加在途的支出金额 并登记日志
planAstLogList.add(planAstManager.itemChangeStage(order.getAccountDate(), planAst, TraderTypeEnum.INITIATOR,
StageChangeTypeEnum.ON_WAY, order.getTransAmt(), transTypeEnum,
order.getBizNo(), JSONUtil.toJsonStr(order)));
});
alloc.setStatus(PlanAllocStatusEnum.PENDING);
alloc.setAllocAmt(order.getTransAmt());
// 3 变更分配计划 更新为分配中 记录分配总额
planAllocManager.updateAllocStatus(alloc);
return order;
}
/**
* 发起创建支付单后
* 1、更新分配计划状态为已分配
* 2、登记分配计划下,各分配事项对应科目的"付"发生额和流水
* @param handleParam
* @param order
* @return
*/
@Override
public PlanCapitalOrder afterHandle(PlanAllocHandleParam handleParam, PlanCapitalOrder order) {
// 线下交易,更新资金交易单的状态为成功
if (handleParam.getOffLine()) {
// 线下支付默认成功 确认金额为交易金额
PlanCapitalFinishRequest finishRequest = new PlanCapitalFinishRequest();
finishRequest.setOutTransNo(handleParam.getOutTransNo());
finishRequest.setSeqNo(order.getSeqNo());
finishRequest.setCfrmAmt(order.getTransAmt());
finishRequest.setRes(TaskStatusEnum.SUCCESS);
finishRequest.setMemo("分配线下支付");
// 更新 资金单据 支付结果 、 变更水位 、科目入账
order = planCapitalOrderManager.finishCapitalOrder(finishRequest);
}
return order;
}
/**
* 解冻冻结金额 目前只面向 分配兑付
* @param curDate
* @param planAst
* @param capitalOrder
* @return
*/
private void unFrozen(List<PlanAstLog> planAstLogList, Date curDate,
PlanAst planAst, PlanCapitalOrder capitalOrder) {
// 查询对应的 分配计划冻结记录 同时获取 对应的锁定金额明细进行解冻
PlanAllocFrozen allocFrozen = planAllocFrozenRepo.getByAllocNo(planAst.getPlanNo(), capitalOrder.getBizNo());
VarChecker.checkNotNull(allocFrozen,
"[{0}]未匹配到对应的冻结记录[{1}]", planAst.getPlanNo(), capitalOrder.getBizNo());
// 判断水位冻结金额 减去 冻结记录金额 后不能小于零
VarChecker.checkArgument(!planAst.getFrozenCash().subtract(allocFrozen.getFrozenCash()).isNegtive(),
"[{0}]计划分配编号[{1}]解冻金额{2} 大于 冻结金额{3}",
planAst.getPlanNo(), capitalOrder.getBizNo(), allocFrozen.getFrozenCash(), planAst.getFrozenCash());
// 冻结金额解冻记录
PlanAstLog planAstLog = PlanAstLog.buildAstLog(curDate, planAst, allocFrozen.getAllocNo(),
TraderTypeEnum.INITIATOR, capitalOrder.getTransType().getTransCode(), StageChangeTypeEnum.UNFROZEN);
planAstLog.changeFrozenCash(planAst, allocFrozen.getFrozenCash(), capitalOrder.getTransAmt(), JSON.toJSONString(allocFrozen));
planAstLogList.add(planAstLog);
// 同时删除冻结金额记录
planAllocFrozenRepo.deleteByAllocNo(planAst.getPlanNo(), capitalOrder.getBizNo());
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.handler;
import cn.hutool.core.util.StrUtil;
import com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanClearingOrderItem;
import com.abssqr.plat.common.facade.enums.AstFlowTypeEnum;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.enums.TransCodeEnum;
import com.abssqr.plat.common.facade.model.org.OrganizationEntity;
import com.abssqr.plat.common.facade.model.plan.PlanAst;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.model.trans.CapitalTrader;
import com.abssqr.plat.common.facade.model.trans.ChangeStageParam;
import com.abssqr.plat.common.model.domain.clearing.SummaryClearingOrder;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.clearing.PlanClearingOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.utils.DayUtil;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.abssqr.plat.core.share.pay.PlanCapitalCreateRequest;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.general.system.common.model.BaseEntity;
import com.general.system.common.model.Money;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import com.general.system.common.util.VarChecker;
import com.general.system.tool.util.ToolUtil;
import org.apache.commons.lang3.tuple.MutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
/**
* 根据结算单 创建 交易支付单
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.handler: PlanAstClearingOrderHandler.java, v 0.1 2019-07-15 01:57 zhenxuan.luo Exp $
*/
@Component
public class PlanAstClearingOrderHandler {
private final static Logger LOGGER = LoggerFactory.getLogger(PlanAstClearingOrderHandler.class);
@Autowired
private PlanClearingOrderRepo planClearingOrderRepo;
@Autowired
private PlanAstStatTaskRepo planAstStatTaskRepo;
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private PlanRepo planRepo;
/**
* 清算 根据结算单生成支付交易单处理
* 事务在任务调用处进行开启
*
* @param entity
*/
public void handle(PlanBase entity) {
// 资产统计任务加锁 判断为等待状态
PlanAstStatTask task = planAstStatTaskRepo.lock(entity.getPlanNo());
if (task == null || task.getStatus() != OrgAstStatStatusEnum.WAIT) {
return;
}
// 拉取待支付的 结算单TaskStatusEnum.INIT
List<PlanClearingOrderItem> orderItemStats =
planClearingOrderRepo.queryByClearingOrderStat(task.getPlanNo(), TaskStatusEnum.INIT, null);
if (ToolUtil.isEmpty(orderItemStats)) {
LogUtil.info(LOGGER, "未找到计划[{0}]待处理结算单", task.getPlanNo());
return;
}
Date accountDate = task.getAccountDate();
// 汇总结算单
List<SummaryClearingOrder> sumOrders = this.calcSummary(orderItemStats);
/**
* 放款池 放款终止日 停止支付标记
* true 代表停止支付直接更新结算单状态
*/
boolean stopPay = this.stopPaySign(entity, accountDate);
// 支付交易单计数
AtomicInteger counter = new AtomicInteger();
Map<String, PlanBase> cntPtyMap = new HashMap<>();
// 更新水位金额变化 及登记流水
planAstManager.changePlanAst(accountDate, entity.getPlanNo(), (planAst, planAstLogList) -> {
// 记录清算在资产水位表中 待结算的收入支出金额变化
// 根据汇总后的结算单 创建交易支付单据
for (SummaryClearingOrder order : sumOrders) {
// 查询对手机构
PlanBase cntPtyPlan = planRepo.getPlanByMapCache(cntPtyMap, order.getCntPtyCode());
// 构建交易双方及交易编码
CapitalTrader capitalTrader = new CapitalTrader(planAst.getPlanNo(), planAst.getPlanType(),
cntPtyPlan.getPlanNo(), cntPtyPlan.getPlanType(), order.getTransCode());
// 获取交易单类型
PlanCapitalTransTypeEnum transType = capitalTrader.getCapitalTransType();
/**
* 支出时 用水位余额 与 交易金额 计算可支出金额,当金额小于等于0时不创建支付单
* 1、支付应付利息时 = 支付应付利息
* 2、其他支出时 = 水位可支出金额 > TransAmt ? TransAmt :水位可支出金额
* 返回值 left 可交易金额 right 备注内容
*/
MutablePair<Money, String> ableTransInfo = this.calcCapitalTransAmt(transType, planAst, order, stopPay);
// 1. 根据实际交易金额与结算单金额 创建支付交易订单 capitalOrder 可交易金额大于零 创建支付单 小于等于零创建his备份
PlanCapitalOrder capitalOrder = this.createCapitalOrder(transType, order, ableTransInfo.getLeft(), counter);
// 2. 更新计划资产水位表 在途的支出收入金额 并登记日志
planAstLogList.addAll(planAstManager.execChangeStageTwoWay(planAst,
ChangeStageParam.createParamByCapital(capitalTrader, StageChangeTypeEnum.ON_WAY, capitalOrder)));
// 3. 修改结算单状态为 SUCCESS,并将capitalOrder交易单的seqNo 回填至ClearingOrder
this.modifyClearingOrderStatus(order, ableTransInfo.getRight().concat(
MessageUtil.formatMsg("-支付单seqNo[{0}]", capitalOrder.getSeqNo())));
}
});
LogUtil.info(LOGGER, "计划[{0}]处理结算单完成,结算单[{1}]条,创建支付订单[{2}]条",
task.getPlanNo(), orderItemStats.size(), counter.get());
}
/**
* 更新结算单状态及回填交易单编号
*
* @param order 结算单
* @param memo 备注
*/
private void modifyClearingOrderStatus(SummaryClearingOrder order, String memo) {
LogUtil.info(LOGGER, memo);
// 根据 初始化状态 的结算单进行更新状态 并将汇总交易编号更新到结算单上
int count = planClearingOrderRepo.updateOrderTransBySeqNos(memo, order.getSeqNos(),
TaskStatusEnum.SUCCESS, order.getTransBizNo(), TaskStatusEnum.INIT);
// 乐观锁控制 是否存在并发处理
if (count != order.getSeqNos().size()) {
String msg = MessageUtil.formatMsg("计划[{0}-{1}]结算单变更[{0}]和任务数[{1}]不一致,等待重新执行",
count, order.getSeqNos().size());
throw new AbssqrBizException(msg, true);
}
}
/**
* 判断当前水位能否进行支付交易 不进行支付交易时返回金额0
*
* @param planAst
* @param order
* @param stopPay
* @return
*/
private MutablePair<Money, String> calcCapitalTransAmt(PlanCapitalTransTypeEnum transType, PlanAst planAst,
SummaryClearingOrder order, boolean stopPay) {
// 返回可交易金额 及 备注
MutablePair<Money, String> pair = new MutablePair(new Money(), "");
/*
承接池
AST_REPO("PCT02", "资产回收兑付"
BUY_AST("PCT03", "资产交易兑付"
GRANT_REVERSE("PCT05", "放款冲正"
-- PAY_HANG_INTR("PCT07", "支付应付利息"
放款池 - 回转放业务
NT_AST_REPO("PCT11", "未转资产回收划账"
NT_BUY_AST("PCT12", "资产交易兑付划账"
-- NT_PAY_HANG_INTR("PCT14", "应付利息兑付回收划账"
*/
// 判断交易对手一致 为放款池回转放业务 进行可支付余额计算 PCT11 PCT12
if (StrUtil.equals(order.getPlanNo(), order.getCntPtyCode())) {
VarChecker.checkArgument(transType == PlanCapitalTransTypeEnum.NT_AST_REPO
|| transType == PlanCapitalTransTypeEnum.NT_BUY_AST
|| transType == PlanCapitalTransTypeEnum.NT_PAY_HANG_INTR,
"{0}[{1}]不支持的交易类型,交易码[{2}],对手方机构号[{3}]", planAst.getPlanType().getCode(),
planAst.getPlanNo(), order.getTransCode().getCode(),order.getCntPtyCode());
if (stopPay) {
// 停止支付时 直接更新结算单状态 不进行支付操作
pair.setRight("放款终止日之后不进行结算支付操作");
return pair;
}
// 水位可支出金额
Money ablePayCash = planAst.ablePayCash().clone();
// 可支出金额 当前水位可用支付余额
Money ablePayAmt = ablePayCash.subtract(order.getTransAmt());
//【水位可用支付余额 小于 交易金额】? 用水位可用支付金额 : 实际交易金额
pair.setLeft(ablePayAmt.isNegtive() ? ablePayCash : order.getTransAmt().clone());
// 水位余额不足 不进行支付操作
if (!pair.getLeft().isGreaterThanZero()) {
pair.setRight(MessageUtil.formatMsg("{0}[{1}]水位不足,TransCode[{2}],amt[{3}],cash[{4}],可用余额[{5}]",
planAst.getPlanType().getCode(), planAst.getPlanNo(), order.getTransCode().getCode(),
order.getTransAmt(), planAst.getCash(), ablePayCash));
}
// 实际支付金额小于应付金额 将差额追加到校验金额上满足后续变更水位校验
Money diffAmt = order.getTransAmt().subtract(pair.getLeft());
if (diffAmt.isGreaterThanZero()){
planAstManager.changeCheckCashAmt(planAst, diffAmt, AstFlowTypeEnum.FLOW_IN);
}
} else {
// 其他情况直接为交易金额
pair.setLeft(order.getTransAmt().clone());
}
return pair;
}
/**
* 创建支付交易单
*
* @param transType 交易单类型
* @param order 结算单
* @param ableTransAmt 实际交易金额
* @param count 计数器
* @return
*/
private PlanCapitalOrder createCapitalOrder(PlanCapitalTransTypeEnum transType, SummaryClearingOrder order,
Money ableTransAmt, AtomicInteger count) {
// 交易类型
PlanCapitalCreateRequest request = new PlanCapitalCreateRequest();
request.setBizNo(order.getTransBizNo());
request.setTransType(transType);
request.setPlanNo(order.getPlanNo());
request.setTargetOrgCode(order.getCntPtyCode());
request.setAccountDate(order.getAccountDate());
// 实际交易金额
request.setTransAmt(ableTransAmt);
// 结算单汇总金额为 应付金额
request.setPayableAmt(order.getTransAmt());
// 返回支付交易单
PlanCapitalOrder capitalOrder = planCapitalOrderManager.createCapitalOrder(request);
LogUtil.info(LOGGER, "{0}[{1}->{2}]创建支付交易单type[{3}]amt[{4}]CapitalOrderSeqNo[{5}]",
order.getAccountDate(), order.getPlanNo(), order.getCntPtyCode(), transType, ableTransAmt, capitalOrder.getSeqNo());
// 订单数 +1
count.getAndIncrement();
return capitalOrder;
}
/**
* 判断放款池的支付标记
*
* @param planBase
* @param accountDate
* @return
*/
private boolean stopPaySign(PlanBase planBase, Date accountDate) {
// 如果是放款池计划 进行冻结预留及 判断转账限制
if (planBase.getPlanType() == PlanTypeEnum.SPV && planBase instanceof OrganizationEntity) {
OrganizationEntity entity = (OrganizationEntity) planBase;
// 计算当前日期与 放款截止日相差天数
int dayDiff = DayUtil.diffDays(new Day(accountDate), new Day(entity.getStopPayDate()));
// 放款截止日后 不进行 回款户向 放款户资金划账打款操作
if (dayDiff >= 0) {
// 直接标记结算单的成功
return true;
}
}
return false;
}
/**
* 汇总计算
*
* @param orderStats
* @return
*/
private List<SummaryClearingOrder> calcSummary(List<PlanClearingOrderItem> orderStats) {
// 按照会计日 交易码 交易对手进行分组汇总数据
Map<ClearingOrderKey, List<PlanClearingOrderItem>> orderStatMap =
orderStats.stream().collect(Collectors.groupingBy(
item -> new ClearingOrderKey(item.getAccountDate(),
TransCodeEnum.getByCode(item.getTransCode()), item.getCntPtyCode())));
// 进行汇总
List<SummaryClearingOrder> summaryList = new ArrayList(orderStatMap.size());
orderStatMap.keySet().forEach(orderKey -> {
SummaryClearingOrder order = new SummaryClearingOrder();
orderStatMap.get(orderKey).stream().forEach(item -> {
order.setPlanNo(item.getPlanNo());
order.setTransCode(TransCodeEnum.getByCode(item.getTransCode()));
order.setCntPtyCode(item.getCntPtyCode());
order.setAccountDate(item.getAccountDate());
order.getTransAmt().addTo(item.getTransAmt());
order.getSeqNos().add(item.getSeqNo());
// 汇总交易编码
String transBizNo = SequenceUtil.genSeqNo(order.getTransCode());
order.setTransBizNo(transBizNo);
});
summaryList.add(order);
});
return summaryList;
}
/**
* 分组 key
*/
private class ClearingOrderKey extends BaseEntity {
/**
* 交易日期
*/
Date accountDate;
/**
* 交易对手
*/
String cntyPtyCode;
/**
* 交易码
*/
TransCodeEnum transCode;
public ClearingOrderKey(Date accountDate, TransCodeEnum transCode, String cntyPtyCode) {
this.cntyPtyCode = cntyPtyCode;
this.transCode = transCode;
this.accountDate = accountDate;
}
}
// // 【原有轧差方案】 3、根据对手机构进行汇总支付与收入,进行轧差计算,创建支付订单,一个对手机构对应一笔支付交易单
// for (Map.Entry<ClearingOrderKey, List<PlanClearingOrderItem>> stat : orderStatMap.entrySet()) {
// ClearingOrderKey orderKey = stat.getKey();
// // 结算单
// List<PlanClearingOrderItem> orderList = stat.getValue();
// List<String> seqNos = orderList.stream().map(PlanClearingOrderItem::getSeqNo).collect(Collectors.toList());
//
// // 轧差计算金额 是支出还是收入,同时更新计划资产水位表,追加在途的支出收入金额,扣减待结算支出收入金额 并登记日志
// MutablePair<PlanCapitalTransTypeEnum, Money> pair = this.calcNetting(orderKey.accountDate, orgEntityCode,
// orderList);
// if (pair.getRight().isZero()) {
// // 收支平衡 没有支付动作,将结算单全部更新成功
// modifyOrderStatus(TaskStatusEnum.SUCCESS, "", seqNos);
// } else {
// // 4、 创建支付订单
// String bizNo = createCapitalOrder(pair.getLeft(), orgEntityCode, orderKey.cntyPtyCode,
// pair.getRight(), orderKey.accountDate);
// count++;
// LogUtil.info(LOGGER, "计划[{0}-{1}]创建支付交易单type[{2}]cntPty[{3}]amt[{4}]bizNo[{5}]",
// orgEntityCode, orderKey.accountDate, pair.getLeft(), orderKey.cntyPtyCode, pair.getRight(),
// bizNo);
// // 5、修改结算单状态为 WAITING,等待支付结果
// modifyOrderStatus(TaskStatusEnum.WAITING, bizNo, seqNos);
// }
// }
// /**
// * 轧差计算金额,同时更新计划资产水位表,追加在途的支出收入金额,扣减待结算支出收入金额 并登记日志
// * @param orderList
// * @return MutablePair <收支类型, 汇总金额>
// */
// @Deprecated
// private MutablePair<PlanCapitalTransTypeEnum, Money> calcNetting(Date accountDate, String planNo,
// List<PlanClearingOrderItem> orderList) {
//
// final Money netAmt = new Money();
// final MutablePair<PlanCapitalTransTypeEnum, Money> triple = new MutablePair<>(null, new Money());
//
// // 6、记录清算在资产水位表中 待结算的收入支出金额变化
// planAstManager.changePlanAst(accountDate, planNo, planAst -> {
//
// List<PlanAstLog> planAstLogList = new ArrayList<>();
//
// for (PlanClearingOrderItem order : orderList) {
// TransCodeEnum transCode = TransCodeEnum.getByCode(order.getTransCode());
// // 流入流出类型
// AstFlowTypeEnum flowTypeEnum = transCode.getFundFlow();
//
// netAmt.addTo(order.getTransAmt().multiply(flowTypeEnum.getSign()));
//
// // 轧差模式,只登记明细的流水,不做实际发生。最后用轧差后的金额进行实际发生
// PlanAstLog planAstLog = PlanAstLog.buildAstLog(planAst, accountDate, transCode,
// StageChangeTypeEnum.NO_CHANGE);
// // 无类型发生额
// planAstLog.setHappenAmt(order.getTransAmt());
// planAstLogList.add(planAstLog);
// }
//
// TransCodeEnum transCode;
// if (triple.getRight().isGreaterThanZero()) {
// // 大于 0 代表收入
// triple.setLeft(PlanCapitalTransTypeEnum.AST_REPO);
// transCode = TransCodeEnum.REPO;
// } else {
// // 支出
// triple.setLeft(PlanCapitalTransTypeEnum.BUY_AST);
// transCode = TransCodeEnum.BUY_AST;
// // 金额转正
// netAmt.multiplyBy(-1L);
// }
//
// triple.setRight(netAmt);
//
// PlanAstLog planAstLog = PlanAstLog.buildAstLog(planAst, accountDate, transCode, StageChangeTypeEnum.ON_WAY);
// // 更新计划资产水位表,追加在途的支出收入金额,扣减待结算支出收入金额 并登记日志
// // 根据 TransCodeEnum 与 StageChangeTypeEnum 进行变更
// planAstLog.changeStageAndLog(planAst, netAmt, netAmt, "");
// planAstLogList.add(planAstLog);
// return planAstLogList;
// });
//
// return triple;
// }
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.handler;
import com.abssqr.plat.common.dal.base.StatEntity;
import com.abssqr.plat.common.dal.mysql.auto.resultmap.LoanClearingLogStat;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.trans.CapitalTrader;
import com.abssqr.plat.common.facade.model.trans.ChangeStageParam;
import com.abssqr.plat.common.facade.model.trans.PlanClearingOrder;
import com.abssqr.plat.common.model.convertor.PlanClearingOrderConvert;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.clearing.PlanClearingLogRepo;
import com.abssqr.plat.common.model.repo.clearing.PlanClearingOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 资产清算统计业务逻辑
*
一 修改内容
1、更改PlanAstStatJob为每日固定时段执行[0 0/5 17-18 * * ? *]\n
2、增加结算单表 PLAN_NO,TRANS_CODE,ACCOUNT_DATE,CNT_PTY_CODE,TRANS_AMT,TRANS_STATUS
TRANS_STATUS: TaskStatusEnum.INIT, EXECUTING, WAITING, SUCCESS
3、水位表增加待清算收入、待清算支出字段
4、修改水位表中获取可用余额的方法,可用余额= 余额Cash - 冻结金额Frozen - 付在途 - 待结算支出 + 待结算收入
二 PlanAstClearingStatHandler 业务
1、获取清算统计前置条件数据(最小id,最大id,总数量);
2、拉取清算汇总数据按PLAN_NO, TRANS_CODE, ACCOUNT_DATE, CNT_PTY_CODE分组;
3、按照汇总结果生成对应结算单1-1;
4、追加水位表中 待结算支出 与 待结算收入 的金额;
三 增加清算支付处理任务
1、拉取待支付的 结算单TaskStatusEnum.INIT,更新为EXECUTING
2、根据对手机构进行汇总支付与收入,进行轧差计算,创建支付订单,一个对手机构对应一笔支付单
PlanCapitalTransTypeEnum 交易类型增加 支付 与 收入 类型进行对应
3、修改结算单状态为 WAITING,等待支付结果
四 增加交易单结果完成后后续处理
1、增加选择处理器,根据不同 PlanCapitalTransTypeEnum 类型,进行对应业务处理剥离 分配兑付与清算
2、清算类型交易单结果处理:
2.1、拉取交易单据对应交易对手的结算单,根据实际确认金额,循环每条扣减金额及更改状态为SUCCESS
2.2、对支付金额不足剩余的 结算单 更改状态为 INIT,等待下次支付
2.3、根据交易单据金额更改扣减水位表的 待结算支出 或 待结算收入 金额
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.handler: PlanAstStatHandler.java, v 0.1 2019-06-12 20:44 zhenxuan.luo Exp $
*/
@Component
public class PlanAstClearingStatHandler {
private final static Logger LOGGER = LoggerFactory.getLogger(PlanAstClearingStatHandler.class);
@Autowired
private PlanClearingLogRepo planClearingLogRepo;
@Autowired
private PlanAstStatTaskRepo planAstStatTaskRepo;
@Autowired
private PlanClearingOrderRepo planClearingOrderRepo;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private PlanRepo planRepo;
/**
* 清算流水统计 为交易准备 生成结算单
* @param planAstStatTask
* @param execTms
* @return
*/
public PlanAstStatTask execute(PlanAstStatTask planAstStatTask, String execTms) {
planAstStatTask.setLastExecTms(execTms);
// 获取清算统计前置条件数据 每 20000 笔统计一次
StatEntity statEntity = planClearingLogRepo.getStatInx(
planAstStatTask.getAccountDate(), planAstStatTask.getPlanNo(), execTms);
if (statEntity == null || statEntity.getCnt() == 0) {
LogUtil.warn(LOGGER, "[{0}]计划清算统计任务[{1}]没有数据execTms={2}",
planAstStatTask.getPlanNo(), planAstStatTask.getAccountDate(), execTms);
planAstStatTask.setStatus(OrgAstStatStatusEnum.WAIT);
planAstStatTaskRepo.updateTask(planAstStatTask);
return planAstStatTask;
}
LogUtil.info(LOGGER, "[{0}]计划清算统计任务[{1}]开始[{2}]条execTms={3}",
planAstStatTask.getPlanNo(), planAstStatTask.getAccountDate(), statEntity.getCnt(), execTms);
// 设置统计数据范围
planAstStatTask.setMinId(statEntity.getMinId());
planAstStatTask.setMaxId(statEntity.getMaxId());
planAstStatTask.setCnt(statEntity.getCnt());
// 拉取清算汇总数据 按 PLAN_NO, TRANS_CODE, ACCOUNT_DATE, CNT_PTY_CODE 分组
List<LoanClearingLogStat> statReses = planClearingLogRepo.clearingLogStat(planAstStatTask.getAccountDate(),
planAstStatTask.getMaxId(),
planAstStatTask.getMinId(),
planAstStatTask.getPlanNo(),
planAstStatTask.getLastExecTms());
long total = 0;
for (LoanClearingLogStat stat : statReses) {
total = total + stat.getCnt();
}
// 并发处理判断
if (total != planAstStatTask.getCnt()) {
LogUtil.warn(LOGGER, "计划统计任务[{0}]汇总条数和分事件汇总条数[{1}]不一致,重新调度", planAstStatTask, total);
planAstStatTask.setStatus(OrgAstStatStatusEnum.WAIT);
planAstStatTaskRepo.updateTask(planAstStatTask);
return planAstStatTask;
}
// 处理统计
planAstStatTask = this.statHandle(statReses, planAstStatTask, execTms);
LogUtil.info(LOGGER, "计划统计任务[{0}]结束, execTms={1}", planAstStatTask, execTms);
return planAstStatTask;
}
/**
* 更新水位 创建结算单 ClearingOrder
* @param statReses
* @param planAstStatTask
* @param execTms
* @return
*/
private PlanAstStatTask statHandle(final List<LoanClearingLogStat> statReses,
final PlanAstStatTask planAstStatTask, String execTms) {
Map<String, PlanBase> cntPtyMap = new HashMap<>();
return transactionTemplate.execute(status -> {
// 对统计任务加锁避免并发
PlanAstStatTask lockedTask = planAstStatTaskRepo.lock(planAstStatTask.getPlanNo());
if (lockedTask.getStatus() != OrgAstStatStatusEnum.PROCESS) {
LogUtil.warn(LOGGER, "计划统计任务[{0}]状态不为处理中,可能存在并发问题", lockedTask);
return lockedTask;
}
if (lockedTask.getMinId() != null && lockedTask.getMinId() >= planAstStatTask.getMinId()) {
throw new AbssqrBizException(
MessageUtil.formatMsg("计划统计任务[{0}]最小ID大于待处理的最小ID[{1}],可能存在并发问题"
, lockedTask, planAstStatTask),
CommonErrorCodeEnum.INVALID_STATUS, true);
}
// locked对象只判断幂等状态不做业务使用
lockedTask = null;
// 更新水位金额变化 及登记流水
planAstManager.changePlanAst(planAstStatTask.getAccountDate(), planAstStatTask.getPlanNo(), (planAst, planAstLogList) -> {
// 记录清算在资产水位表中 待结算的收入支出金额变化
for (LoanClearingLogStat statRes : statReses) {
LogUtil.info(LOGGER, "计划统计结果:planNo={0}, accountDate={1} | statTask={2} | statRes={3}",
planAstStatTask.getPlanNo(), planAstStatTask.getAccountDate(), planAstStatTask, statRes);
// 汇总金额
if (statRes.getAmt().isGreaterThanZero()) {
// 1. 创建结算单
PlanClearingOrder clearingOrder = PlanClearingOrderConvert.convert2Domain(statRes, execTms);
planClearingOrderRepo.createOrder(clearingOrder);
LogUtil.info(LOGGER, "计划资产清算汇总结算单:【{0}】---【{1}】",
clearingOrder, planAstStatTask);
// 2. 备份ClearingLog 将ClearingOrder的 seqNo 回填
planClearingLogRepo.backStated(
clearingOrder.getSeqNo(), planAstStatTask.getLastExecTms(), statRes);
// 查询对手机构
PlanBase cntPtyPlan = planRepo.getPlanByMapCache(cntPtyMap, statRes.getCntPtyCode());
// 构建交易双方及交易编码
CapitalTrader capitalTrader = new CapitalTrader(planAst.getPlanNo(), planAst.getPlanType(),
cntPtyPlan.getPlanNo(), cntPtyPlan.getPlanType(), clearingOrder.getTransCode());
planAstLogList.addAll(planAstManager.execChangeStageTwoWay(planAst,
ChangeStageParam.createParamByClearing(capitalTrader, StageChangeTypeEnum.CLEAR, clearingOrder)));
}
}
});
// 4. 删除清算流水
int refCnt = planClearingLogRepo.deleteStated(
planAstStatTask.getAccountDate(), planAstStatTask.getMaxId(),
planAstStatTask.getMinId(), planAstStatTask.getPlanNo(), planAstStatTask.getLastExecTms());
if (refCnt != planAstStatTask.getCnt()) {
throw new AbssqrBizException(
MessageUtil.formatMsg("计划统计任务统计流水变更[{0}]和任务删除数[{1}]不一致", planAstStatTask, refCnt),
CommonErrorCodeEnum.INVALID_STATUS, true);
}
LogUtil.info(LOGGER, "计划统计任务[{0}]结束, execTms={1},汇总流水数[{2}]", planAstStatTask, execTms, refCnt);
// 5. 更新任务状态,等待下一次调度
planAstStatTask.setStatus(OrgAstStatStatusEnum.WAIT);
planAstStatTaskRepo.updateTask(planAstStatTask);
return planAstStatTask;
});
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.handler;
import com.abssqr.plat.common.facade.enums.AbssqrNoticeTypeEnum;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.enums.TransCodeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.model.domain.plan.PlanAstLog;
import com.abssqr.plat.common.model.enums.TraderTypeEnum;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.AstSyncTaskComponent;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.acct.AcctManager;
import com.abssqr.plat.core.service.notice.AbssqrNoticeManager;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.general.system.common.model.Money;
import com.general.system.common.util.*;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
import java.util.Optional;
/**
* 资金到账情况
* @author hanfei
* @version $Id: PlanFundHandler.java, v 0.1 2019-09-10 3:28 PM hanfei Exp $
*/
@Component
public class PlanFundHandler {
private final static Logger LOGGER = LoggerFactory.getLogger(PlanFundHandler.class);
@Autowired
private WkPayManager wkPayManager;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private AcctManager acctManager;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private AbssqrNoticeManager abssqrNoticeManager;
@Autowired
private AstSyncTaskComponent astSyncTaskComponent;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 资金到账情况 执行余额查询
* 1、查询当前 状态为 存续中 放款池计划 与 承接池计划
* 2、获取计划对应资金账户
* 3、查询账户余额
* 4、更新资金账户余额
* 是init初始: "AST1015", "投入资本" ,"add", "水位增加"。修改状态为success
* 是success非初始:计算银行余额 与 账户余额 差值,
* 多余的进行增加水位余额,条目为 "AST1013", "资金调整增加","add", "水位增加"
* 计算少于的扣减水位余额,条目为 "AST1014", "资金调整减少","sub", "水位扣减"
* @param entity
* @param curDate
* @throws JobExecutionException
*/
public void executeQueryBalance(PlanBase entity, Day curDate) {
// 校验是否需有未完成支付单
if (planCapitalOrderManager.checkExistCapital(entity.getPlanNo())) {
return;
}
// 对于 放款池计划需要校验 当日资产同步是否已经完成 账务资金是否对账完成 避免 还款提前入银行账,导致水位加错
if (astSyncTaskComponent.cantBankBalance(entity, curDate)) {
return;
}
// 1、获取计划对应资金账户 平台虚拟户
List<Account> accounts = acctManager.getAcctByPlanNoAndType(
entity.getPlanNo(), AccountTypeEnum.PLAT_VIRTUAL,false);
AccountAttributeEnum attr;
if (entity.getPlanType() == PlanTypeEnum.SPV) {
// 放款池计划 查询回款户
attr = AccountAttributeEnum.RECV;
} else {
// 承接池计划 查询一般业务户
attr = AccountAttributeEnum.NORMAL;
}
// 过滤出对应查询余额的账户
Optional<Account> platAcctOpt = accounts.stream()
.filter(item -> item.getActAttr() == attr)
.findFirst();
VarChecker.checkArgument(platAcctOpt.isPresent(),
"{0}[{1}]找不到[{2}]对应平台虚拟户", entity.getPlanType().getDesc(), entity.getPlanNo(), attr.getDesc());
Account planAcct = platAcctOpt.get();
Money bankBal = new Money();
try {
// 3、调用外部接口查询账户余额
WkChannelNoEnum channelNo = WkChannelNoEnum.getPlatChannelNo(planAcct.getChannelNo());
bankBal.addTo(wkPayManager.balance(planAcct.getActNo(), channelNo));
LogUtil.info(LOGGER, "{0}[{1}]查询账户余额: {2}",
entity.getPlanType().getDesc(), entity.getPlanNo(), bankBal.getAmount());
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "[{0}]-ChannelNo[{1}]-ActNo[{2}]调用五矿查询账户余额异常",
entity.getPlanNo(), planAcct.getChannelNo(), planAcct.getActNo());
throw e;
}
final String entityNo = entity.getPlanNo();
transactionTemplate.execute(status -> {
// 4、变更水位表
planAstManager.changePlanAst(curDate.getStandardDate(), entityNo, (planAst, planAstLogList) -> {
if (planAst.getStatus() == TaskStatusEnum.INIT) {
if (bankBal.isZero()) {
LogUtil.info(LOGGER, "{0}[{1}]查询银行账户余额: 余额为0,不进行处理",
planAst.getPlanType().getDesc(), planAst.getPlanNo());
return;
}
// 账户余额初始化
PlanAstLog planAstLog = PlanAstLog.buildAstLog(curDate.getStandardDate(), planAst, entityNo,
TraderTypeEnum.INITIATOR, TransCodeEnum.CAP_INVEST, StageChangeTypeEnum.ADD);
// 资本增加
planAstLog.bankSyncChangeStageAndLog(planAst, bankBal, bankBal, "投入资本到账");
planAstLogList.add(planAstLog);
// 完成初始化 更新状态
planAst.setStatus(TaskStatusEnum.SUCCESS);
} else {
// 判断在途金额非0时不查询
if (planAst.getRepoOnWay().isGreaterThanZero()
|| planAst.getPayOnWay().isGreaterThanZero()) {
LogUtil.error(LOGGER, "{0}[{1}]账户水位在途金额不为0: [{2}], [{3}]",
planAst.getPlanType().getDesc(), planAst.getPlanNo(), planAst.getRepoOnWay(),
planAst.getPayOnWay());
return;
}
/**
* 判断系统时间与获取会计日 是否是同一天,非同一天不进行查询账户余额
* 非使用系统时间下不进行余额校验查询
* 针对放款池会在curDate+1日将还款提前打入账户,防止重复加水位
*/
if (!curDate.equalSysDate()) {
return;
}
// 计算 银行账户余额 与 系统账户余额 差值
Money diffAmt = bankBal.subtract(planAst.getCash());
// 无金额变化
if (diffAmt.isZero()) {
LogUtil.info(LOGGER, "{0}[{1}]账户余额核对: 银行余额[{2}], 本地余额[{3}],差异金额为0",
planAst.getPlanType().getDesc(), planAst.getPlanNo(), bankBal, planAst.getCash());
return;
}
TransCodeEnum transCode;
if (diffAmt.isGreaterThanZero()) {
// 资金增加
transCode = TransCodeEnum.CAP_ADJ_ADD;
} else {
// 资金减少 改为 不进行变动 进行告警通知 银行账户余额 与水位余额 存在短账
String content = MessageUtil.formatMsg(
"{0}[{1}]账户余额核对短帐: 银行余额[{2}], 本地余额[{3}],差异金额为[{4}],请排查银行账户短帐具体原因!",
planAst.getPlanType().getDesc(), planAst.getPlanNo(), bankBal, planAst.getCash(),
diffAmt);
abssqrNoticeManager.sendBusinessNotice(entity, planAcct.getActNo(),
AbssqrNoticeTypeEnum.BankFundBal, content,
abssqrNoticeManager.getAdminReceivers());
return;
}
LogUtil.info(LOGGER, "{0}[{1}]账户余额核对: 银行余额[{2}], 本地余额[{3}],差异金额为[{4}]",
planAst.getPlanType().getDesc(), planAst.getPlanNo(), bankBal, planAst.getCash(), diffAmt);
PlanAstLog planAstLog = PlanAstLog.buildAstLog(curDate.getStandardDate(), planAst, entityNo,
TraderTypeEnum.INITIATOR, transCode, StageChangeTypeEnum.BANK_BAL_CHECK);
planAstLog.bankSyncChangeStageAndLog(planAst, diffAmt, bankBal, "每日账户余额核对资金变化");
planAstLogList.add(planAstLog);
}
});
return null;
});
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.handler;
import cn.hutool.core.collection.CollectionUtil;
import com.abssqr.plat.biz.shared.listener.PlanMonitorRecordEvent;
import com.abssqr.plat.biz.shared.report.WkPlanReportChecker;
import com.abssqr.plat.biz.shared.report.wk.WkAstReportBuilder;
import com.abssqr.plat.biz.shared.report.wk.WkManagerReportBuilder;
import com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanAstReportStat;
import com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanStatItem;
import com.abssqr.plat.common.facade.enums.EventCodeEnum;
import com.abssqr.plat.common.facade.enums.ReportTitleGroupEnum;
import com.abssqr.plat.common.facade.enums.ReportTypeEnum;
import com.abssqr.plat.common.facade.enums.TitleTypeEnum;
import com.abssqr.plat.common.facade.model.plan.PlanAcctTitle;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.report.DailyReportDateField;
import com.abssqr.plat.common.facade.model.report.MonthReportDateField;
import com.abssqr.plat.common.facade.model.report.PlanReport;
import com.abssqr.plat.common.facade.model.report.PlanReportItem;
import com.abssqr.plat.common.facade.model.report.wk.WkManagerReport;
import com.abssqr.plat.common.model.domain.plan.PlanAcctTitleLog;
import com.abssqr.plat.common.model.enums.IdTypeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanAcctTitleLogRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAcctTitleRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAstLogRepository;
import com.abssqr.plat.common.model.repo.report.PlanReportEntityRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportEntityStatRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.core.service.report.LoanBakStatManager;
import com.alibaba.fastjson.JSON;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.tuple.MutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 计划报表统计任务
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.scheduler.job.plan: PlanPackGenJob.java, v 0.1 2019-06-18 21:19 zhenxuan.luo
* Exp $
*/
@Component
public class WkPlanReportHandler {
protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
@Autowired
private ApplicationContext applicationContext;
@Autowired
private PlanReportEntityRepo planReportEntityRepo;
@Autowired
private PlanAstLogRepository planAstLogRepository;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private WkAstReportBuilder wkAstReportBuilder;
@Autowired
private WkManagerReportBuilder wkManagerReportBuilder;
@Autowired
private PlanReportRepo planReportRepo;
@Autowired
private PlanReportEntityStatRepo planReportEntityStatRepo;
@Autowired
private WkPlanReportChecker wkPlanReportChecker;
@Autowired
private PlanAcctTitleLogRepo planAcctTitleLogRepo;
@Autowired
private PlanAcctTitleRepo planAcctTitleRepo;
@Autowired
private LoanBakStatManager loanBakStatManager;
/**
* 执行报表
* @param accountDate
* @param planBase
* @return
*/
public MutablePair<Boolean, String> execute(Date accountDate, PlanBase planBase) {
// 日报组装
MutablePair<Boolean, String> resultRptPair = checkAndBuildDailyAstReport(accountDate, planBase);
if (resultRptPair.getLeft()){
// 月报组装
checkAndBuildMonthPlanReport(accountDate, planBase);
}
return resultRptPair;
}
/**
* 日报表组装
*
* @param accountDate
* @param planBase
*/
public MutablePair<Boolean, String> checkAndBuildDailyAstReport(Date accountDate, PlanBase planBase) {
// 查询最近的报表,若存在,则直接取下一个周期进行生成,避免中间因为系统故障导致报表没有生成的问题。
PlanReport planReport = planReportRepo.getLatestReport(planBase.getPlanNo(), ReportTypeEnum.RPT001);
// 日期控制对象
DailyReportDateField reportDateField = new DailyReportDateField();
// 放款池计划时 对应的承接池报表编号
List<String> planNos = Lists.newArrayList();
// 校验报表是否可执行
MutablePair<Boolean, String> rptResultPair =
wkPlanReportChecker.checkDailyAstReport(accountDate, planBase, planReport, reportDateField, planNos);
if (!rptResultPair.getLeft()){
return rptResultPair;
}
// 组装报表数据
buildDailyAstReport(reportDateField, planBase, planReport, planNos);
return rptResultPair;
}
/**
* 组装报表数据
* @param reportDateField 日期控制
* @param planBase 计划
* @param lastReport 最后一日报表
* @param planNos 放款池时对应承接池计划编号
*/
public void buildDailyAstReport(DailyReportDateField reportDateField, PlanBase planBase,
PlanReport lastReport, List<String> planNos) {
LogUtil.info(LOGGER, "[ReportJob]-[{0}]计划在[{1}]-[{2}]报表生成任务执行*开始*",
planBase.getPlanNo(), reportDateField.getAccountDate(), ReportTypeEnum.RPT001);
//余额项统计 使用loanBak统计余额
List<PlanAstReportStat> statLoanBakBal =
loanBakStatManager.statLoanBakBal(reportDateField.getAccountDate(), planBase);
//发生额项统计
List<PlanAstReportStat> statAmt =
planReportEntityRepo.statAmt(reportDateField.getAccountDate(), planBase.getPlanNo());
//每日结息项统计
List<PlanAstReportStat> statAccrued =
planReportEntityRepo.statAccrued(reportDateField.getAccountDate(), planBase.getPlanNo());
//资金项统计-->水位变更
List<PlanStatItem> planStatItems =
planAstLogRepository.getAstLogStat(reportDateField.getAccountDate(), planBase.getPlanNo());
// 获取需要统计的科目流水
Map<ReportTitleGroupEnum, List<PlanAcctTitleLog>> acctTitleLogMap =
this.getTitleLogMap(reportDateField.getAccountDate(), planBase.getPlanNo());
transactionTemplate.execute(status -> {
// 组装日报
List<PlanReportItem> planReportItems = wkAstReportBuilder.buildReport(planBase,
lastReport, reportDateField, statLoanBakBal, statAmt, statAccrued, planStatItems, acctTitleLogMap, planNos);
PlanReport newReport = new PlanReport();
newReport.setRptNo(SequenceUtil.genId(IdTypeEnum.SEQ));
newReport.setPlanNo(planBase.getPlanNo());
newReport.setPlanName(planBase.getPlanName());
newReport.setRptDate(reportDateField);
newReport.setRptType(ReportTypeEnum.RPT001);
newReport.addReportItems(planReportItems);
// 创建报表
planReportRepo.create(newReport);
// 备份资产统计的中间结果,备查
planReportEntityStatRepo.insertBatch(statLoanBakBal);
//
planReportEntityStatRepo.insertBatch(statAmt);
// 数据量较大,定期清理
// planReportEntityRepo.delete(reportDateField.getAccountDate(), plan.getPlanNo());
//更新监控指标
applicationContext.publishEvent(new PlanMonitorRecordEvent(this, newReport, planBase));
return newReport;
});
LogUtil.info(LOGGER, "[ReportJob]-[{0}]计划在[{1}]-[{2}]报表生成任务执行*结束*",
planBase.getPlanNo(), reportDateField.getAccountDate(), ReportTypeEnum.RPT001);
}
/**
* 月报组装
*
* @param accountDate
* @param plan
*/
public MutablePair<Boolean, String> checkAndBuildMonthPlanReport(Date accountDate, PlanBase plan) {
// 查询最近的报表,若存在,则直接取下一个周期进行生成,避免中间因为系统故障导致报表没有生成的问题。
PlanReport latestReport = planReportRepo.getLatestReport(plan.getPlanNo(), ReportTypeEnum.RPT002);
MonthReportDateField reportMonthField = new MonthReportDateField();
// 执行校验
MutablePair<Boolean, String> rptResultPair =
wkPlanReportChecker.checkMonthPlanReport(accountDate, plan, latestReport, reportMonthField);
if (!rptResultPair.getLeft()){
return rptResultPair;
}
// 组装生成月报
buildMonthPlanReport(reportMonthField, plan, latestReport);
return rptResultPair;
}
/**
* 组装生成月报
* @param reportMonthField 日期控制
* @param plan 计划
* @param latestReport 上一报表
*/
public void buildMonthPlanReport(MonthReportDateField reportMonthField, PlanBase plan,
PlanReport latestReport) {
Date startDate = DateTimeUtil.getMax(plan.getBeginDate(), reportMonthField.getRptStartDate());
Date endDate = reportMonthField.getAccountDate();
LogUtil.info(LOGGER, "[buildMonthPlanReport]-[{0}]计划在[{1}]-[{2}]管理报表生成任务执行*开始*[{3}]",
plan.getPlanNo(), startDate, endDate ,ReportTypeEnum.RPT002 );
// 上一期报表
WkManagerReport lastManagerRpt = (latestReport == null) ? null :
JSON.parseObject(latestReport.getDetail(), WkManagerReport.class);
// 科目
List<PlanAcctTitle> planAcctTitles = planAcctTitleRepo.getByEntityNo(plan.getPlanNo());
// 科目流水
List<PlanAcctTitleLog> titleLogs = planAcctTitleLogRepo.getByDate(plan.getPlanNo(), startDate, endDate);
// 生成管理报表
WkManagerReport curReport = wkManagerReportBuilder.buildReport(
plan, startDate, endDate, lastManagerRpt, planAcctTitles, titleLogs);
transactionTemplate.execute(status -> {
PlanReport newReport = new PlanReport();
newReport.setRptNo(SequenceUtil.genId(IdTypeEnum.SEQ));
newReport.setPlanNo(plan.getPlanNo());
newReport.setPlanName(plan.getPlanName());
newReport.setRptDate(reportMonthField);
newReport.setRptType(ReportTypeEnum.RPT002);
newReport.setDetail(JSON.toJSONString(curReport));
// 创建报表
planReportRepo.create(newReport);
return newReport;
});
LogUtil.info(LOGGER, "[buildMonthPlanReport]-[{0}]计划在[{1}]-[{2}]管理报表生成任务执行*结束*[{3}]",
plan.getPlanNo(), startDate, endDate, curReport);
}
/**
* 获取 投资结构余额及相关费用的科目流水
* @param accountDate
* @param planNo
* @return
*/
private Map<ReportTitleGroupEnum, List<PlanAcctTitleLog>> getTitleLogMap(Date accountDate, String planNo){
Map<ReportTitleGroupEnum, List<PlanAcctTitleLog>> acctTitleLogMap = new HashMap<>();
//金融服务费统计
PlanAcctTitleLog finFee = planAcctTitleLogRepo.getSettleFinFee(accountDate, planNo);
acctTitleLogMap.put(ReportTitleGroupEnum.FIN_SER_FEE, Lists.newArrayList(finFee));
// 本金科目
List<TitleTypeEnum> investedEnums =
CollectionUtil.newArrayList(TitleTypeEnum.INVESTED, TitleTypeEnum.PRIOR_INVESTED, TitleTypeEnum.SECND_INVESTED);
// 查询计划投资结构本金分配科目流水
PlanAcctTitleLog invested = planAcctTitleLogRepo.getAcctTitleByType(accountDate, planNo,
EventCodeEnum.TITLE_ALLOC, investedEnums);
acctTitleLogMap.put(ReportTitleGroupEnum.INVESTED_DAY, Lists.newArrayList(invested));
// 获取所有兑付流水
List<PlanAcctTitleLog> allTitleLogs = planAcctTitleLogRepo.getByPlanAndEvent(
null, planNo, EventCodeEnum.TITLE_ALLOC, investedEnums);
acctTitleLogMap.put(ReportTitleGroupEnum.INVESTED_ALL, Lists.newArrayList(allTitleLogs));
return acctTitleLogMap;
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.report;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.ReportTypeEnum;
import com.abssqr.plat.common.facade.enums.SyncTaskTypeEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.report.DailyReportDateField;
import com.abssqr.plat.common.facade.model.report.MonthReportDateField;
import com.abssqr.plat.common.facade.model.report.PlanReport;
import com.abssqr.plat.common.model.repo.clearing.PlanClearingLogRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.abssqr.plat.core.service.plan.PlanSyncTaskCtrManager;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
*
* @author hanfei
* @version $Id: WkPlanReportChecker.java, v 0.1 2019-12-30 10:29 PM hanfei Exp $
*/
@Component
public class WkPlanReportChecker {
protected final Logger LOGGER = LoggerFactory.getLogger(getClass());
@Autowired
private PlanSyncTaskCtrManager planSyncTaskCtrManager;
@Autowired
private PlanManager planManager;
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private PlanClearingLogRepo planClearingLogRepo;
@Autowired
private PlanReportRepo planReportRepo;
/**
* 日报生成校验,报表日:
* 1、数据同步任务
* 2、金融服务费统计
* 3、结算单或支付单
* 4、清算流水
* 5、放款池,判断承接池报表生成
* @param accountDate 机构会计日
* @param planBase
* @param planReport
* @param reportDateField
* @param planNos
* @return
*/
public MutablePair<Boolean, String> checkDailyAstReport(Date accountDate, PlanBase planBase,
PlanReport planReport,
DailyReportDateField reportDateField,
List<String> planNos){
MutablePair<Boolean, String> rptResultPair = new MutablePair<>(true, "");
if (null != planReport) {
// 最近日期报表日
reportDateField.setRptDate(planReport.getRptDate().getAccountDate());
// 最近日期报表日 大于 机构会计日 不生成
if (DateTimeUtil.calcDayDiff(reportDateField.getAccountDate(), accountDate) >= 0) {
LogUtil.info(LOGGER, "[ReportJob]-[{0}]计划在[{1}]日报表已经生成",
planBase.getPlanNo(), reportDateField.desc());
return rptResultPair;
}
// 设置下一天
reportDateField.toNext();
} else {
// 没有报表 直接设置机构会计日
reportDateField.parse(DateTimeUtil.formatYMD(accountDate));
}
// 判断当前机构会计日 数据同步,校验数据同步和模型转换是否完成
Date orgDate = DateTimeUtil.getStandardDate(reportDateField.getAccountDate());
if (!planSyncTaskCtrManager.checkSyncFinishGtIsTrue(planBase, orgDate, SyncTaskTypeEnum.AST_MOD)) {
rptResultPair.setRight(MessageUtil.formatMsg("[ReportJob]-[{0}]计划在[{1}]的数据同步任务未完成",
planBase.getPlanNo(), orgDate));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
// 判断当前机构会计日 金融服务费
if (!planSyncTaskCtrManager.checkSyncFinishGtIsTrue(planBase, orgDate, SyncTaskTypeEnum.AST_SER_FEE)) {
rptResultPair.setRight(MessageUtil.formatMsg("[ReportJob]-[{0}]计划在[{1}]的金融服务费统计未完成",
planBase.getPlanNo(), orgDate));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
// 查询计划当前未完成结算单及交易支付单的数量
int unfinishCapitalCnt = planCapitalOrderManager
.reportCheckCapitals(planBase.getPlanNo(), new Day(reportDateField.getAccountDate()));
if (unfinishCapitalCnt > 0) {
rptResultPair.setRight(MessageUtil.formatMsg("[ReportJob]-[{0}]计划在[{1}]的资金处理(结算单或支付单)有[{2}]条未处理完毕",
planBase.getPlanNo(), reportDateField.getAccountDate(), unfinishCapitalCnt));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
Date unfinishClearingLogDate = planClearingLogRepo.getMinUnStateAccountDate(planBase.getPlanNo(), null);
if (unfinishClearingLogDate != null
&& DateTimeUtil.calcDayDiff(reportDateField.getAccountDate(), unfinishClearingLogDate) >= 0) {
rptResultPair.setRight(MessageUtil.formatMsg("[ReportJob]-[{0}]计划在[{1}]的清算日志未汇总完成,最小日志会计日期为[{2}],不执行报表生成",
planBase.getPlanNo(), reportDateField.getAccountDate(), unfinishClearingLogDate));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
if (planBase.getPlanType() == PlanTypeEnum.SPV) {
//获取受让计划
List<String> planNosBySpvNo =Lists.newArrayList();
Map<String, List<PlanBase>> planBySpvs = planManager.getPlanBySpvs(Lists.newArrayList(planBase.getPlanNo()));
if(MapUtils.isNotEmpty(planBySpvs)){
List<PlanBase> planBases = planBySpvs.get(planBase.getPlanNo());
for(PlanBase pb : planBases){
if(DateTimeUtil.calcDayDiff(reportDateField.getAccountDate(),
DateTimeUtil.getStandardDate(pb.getEffectDate()))>=0){
planNosBySpvNo.add(pb.getPlanNo());
}
}
}
if (CollectionUtils.isNotEmpty(planNosBySpvNo)) {
planNos.addAll(planNosBySpvNo);
if (!planReportRepo.allFinished(planNos, reportDateField.desc(), ReportTypeEnum.RPT001)) {
rptResultPair.setRight(MessageUtil.formatMsg("[ReportJob]-[{0}]计划下受让计划[{1}]在[{2}]的日报未完成",
planBase.getPlanNo(), planNos, orgDate));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
}
}
return rptResultPair;
}
/**
* 月报校验
* @param accountDate
* @param plan
* @param latestReport
* @param reportMonthField
* @return
*/
public MutablePair<Boolean, String> checkMonthPlanReport(Date accountDate, PlanBase plan,
PlanReport latestReport,
MonthReportDateField reportMonthField) {
MutablePair<Boolean, String> rptResultPair = new MutablePair<>(true, "");
/**
* 计算当前应该出哪个月的报表: reportMonth
*/
Date nextMonthCk = DateTimeUtil.addDays(accountDate, 1);
Date reportMonth;
if (DateTimeUtil.calMonthDiff(accountDate, nextMonthCk) > 0) {
// 当前会计日期是每个月最后一天
reportMonth = accountDate;
} else {
Date monthFirstDay = DateTimeUtil.parseFromYMD(
DateTimeUtil.format(accountDate, DateTimeUtil.FORMAT_DATE_YYYYMM + "01"));
reportMonth = DateTimeUtil.addDays(monthFirstDay, -1);
}
/**
* 根据历史已出报表(可能没出)计算应该出哪个月,从已出那个月递增:reportDateField
*/
if (null != latestReport) {
String reportMonthText = DateTimeUtil.format(reportMonth, DateTimeUtil.FORMAT_DATE_YYYYMM);
reportMonthField.parse(reportMonthText);
MonthReportDateField lastReportDateField = (MonthReportDateField) latestReport.getRptDate();
if (!lastReportDateField.isEarlier(reportMonthField)) {
rptResultPair.setRight(MessageUtil.formatMsg("[buildMonthPlanReport]-[{0}]计划在[{1}]的月管理报表已经生成",
plan.getPlanNo(), reportMonthField.desc()));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
reportMonthField.parse(lastReportDateField.toNext().desc());
} else {
// 从未有月报,从计划生效日开始处理
reportMonthField.parse(DateTimeUtil.format(plan.getBeginDate(), DateTimeUtil.FORMAT_DATE_YYYYMM));
}
// 判断月报最后一天(月末)是否大于当前会计日期,如果是,则不生成报表(还未到月末)
if (DateTimeUtil.calcDayDiff(reportMonthField.getAccountDate(), accountDate) > 0) {
rptResultPair.setRight(MessageUtil.formatMsg("[buildMonthPlanReport]-[{0}]计划月报日期[{1}]大于当前会计日期[{2}],不生成计划报表",
plan.getPlanNo(), reportMonthField, accountDate));
LogUtil.info(LOGGER, rptResultPair.getRight());
// 不是每月最后一天,不生成报表
rptResultPair.setLeft(false);
return rptResultPair;
}
/**
* ------- 日期判断结束,开始生成报表 -------
*/
// 检查上日日报是否汇总完成
DailyReportDateField lastDailyReportDate = new DailyReportDateField();
lastDailyReportDate.setRptDate(reportMonthField.getAccountDate());
PlanReport dailyReport = planReportRepo.getReport(
plan.getPlanNo(), ReportTypeEnum.RPT001, lastDailyReportDate.desc());
if (dailyReport == null) {
rptResultPair.setRight(MessageUtil.formatMsg("[buildMonthPlanReport]-[{0}]计划在[{1}]的日报任务未完成",
plan.getPlanNo(), lastDailyReportDate.desc()));
LogUtil.info(LOGGER, rptResultPair.getRight());
rptResultPair.setLeft(false);
return rptResultPair;
}
return rptResultPair;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.keeper.node;
import com.abssqr.plat.common.facade.enums.AbssqrNoticeTypeEnum;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanTaskTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.org.OrganizationEntity;
import com.abssqr.plat.common.facade.model.plan.PlanAst;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.model.domain.plan.PlanTaskLog;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.repo.plan.PlanTaskLogRepo;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.acct.AcctManager;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.general.system.common.model.IEnum;
import com.general.system.common.model.Money;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* 每日余额校验
*
* @author xiachenxiang
* @version com.abssqr.plat.biz.shared.scheduler.job.keeper.node: BalanceCheckKeeper.java, v 0.1 2019-10-08 11:01 AM xiachenxiang Exp $
*/
@Component
public class BalanceCheckKeeper extends AbstractKeeperNode {
@Autowired
private PlanTaskLogRepo planTaskLogRepo;
@Autowired
private PlanRepo planRepo;
@Autowired
private AcctManager acctManager;
@Autowired
private WkPayManager wkPayManager;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@Value("${wkabs.zhaolian.balancecheck.deadline:8 0 0}")
private String deadline;
@Override
protected Void doHandle(Date currentTime) {
LogUtil.info(LOGGER, "每日余额校验-start");
currentTime = getCurrentStanderDate();
// 判断当前时间是否大于凌晨1点
Date deadlineTime = getDeadLineTime(currentTime, deadline);
if (currentTime.compareTo(deadlineTime) > 0) {
Date bizDate = orgAcctDayComponent.getTrfAcctDay().getStandardDate();
List<PlanTaskLog> tasks = planTaskLogRepo.getTasks(bizDate, PlanTaskTypeEnum.BAL_CHECKER);
// 查询存续中的放款池计划
List<PlanBase> onGoingPlans = planRepo.getPlansByStatus(PlanTypeEnum.SPV, PlanStatusEnum.ONGOING);
StringBuffer sb = new StringBuffer();
for (PlanBase plan : onGoingPlans) {
boolean isExist = false;
boolean isStop = false;
if (CollectionUtils.isNotEmpty(tasks)) {
isExist = tasks.stream().filter(item -> item.getPlanNo().equals(plan.getPlanNo()) && item.getTaskType() == PlanTaskTypeEnum.BAL_CHECKER).findFirst().isPresent();
}
if (plan instanceof OrganizationEntity) {
OrganizationEntity organizationEntity = (OrganizationEntity) plan;
isStop = DateTimeUtil.calcDayDiff(orgAcctDayComponent.getTrfAcctDay().getStandardDate(), organizationEntity.getStopPayDate()) > 0;
if (isStop) {
LogUtil.info(LOGGER, "计划编号{0},当前会计日{1}大于停止放款日期{2},{3}",
plan.getPlanNo(), currentTime, organizationEntity.getStopPayDate(), isStop);
}
}
if (!isExist && !isStop) {
// 获取计划对应资金账户 平台虚拟户
List<Account> accounts = acctManager.getAcctByPlanNoAndType(plan.getPlanNo(), AccountTypeEnum.PLAT_VIRTUAL, false);
// 过滤出对应查询余额的账户
Optional<Account> platAcctOpt = accounts.stream()
.filter(item -> item.getActAttr() == AccountAttributeEnum.RECV)
.findFirst();
// 异常打印后继续
if (!platAcctOpt.isPresent()) {
LogUtil.error(LOGGER, "{0}[{1}]找不到[{2}]对应平台虚拟户", plan.getPlanType().getDesc(), plan.getPlanNo(), AccountAttributeEnum.RECV.getDesc());
continue;
}
Account planAcct = platAcctOpt.get();
Money bankBal = new Money();
try {
// 调用外部接口查询账户余额
WkChannelNoEnum channelNo = WkChannelNoEnum.getPlatChannelNo(planAcct.getChannelNo());
bankBal.addTo(wkPayManager.balance(planAcct.getActNo(), channelNo));
LogUtil.info(LOGGER, "{0}[{1}]查询账户余额: {2}", plan.getPlanType().getDesc(), plan.getPlanNo(), bankBal.getAmount());
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "[{0}]-ChannelNo[{1}]-ActNo[{2}]调用五矿查询账户余额异常",
plan.getPlanNo(), planAcct.getChannelNo(), planAcct.getActNo());
continue;
}
if (bankBal.compareTo(new Money()) > 0) {
PlanAst planAst = planAstManager.getByPlanNo(plan.getPlanNo());
if (bankBal.subtract(planAst.getFrozenCash()).isGreaterThanZero()) {
String msg = MessageUtil.formatMsg("截止到{0}为止,{1}[{2}]查询账户余额为 {3},请排查具体原因 \n", DateTimeUtil.formatYMDHMSSLong(currentTime), plan.getPlanType().getDesc(), plan.getPlanNo(), bankBal.getAmount());
sb.append(msg);
}
}
PlanTaskLog planTaskLog = new PlanTaskLog();
planTaskLog.setExecDate(bizDate);
planTaskLog.setPlanNo(plan.getPlanNo());
planTaskLog.setTaskType(PlanTaskTypeEnum.BAL_CHECKER);
planTaskLogRepo.createTask(planTaskLog);
}
}
if (sb.length() > 0) {
// 获取用户
Set<String> receivers = getAdminReceivers();
sendSystemNotice("每日余额校验异常告警", "ALL", sb.toString(), receivers);
}
}
LogUtil.info(LOGGER, "每日余额校验-end");
return null;
}
@Override
protected String getWatchJob() {
return null;
}
@Override
protected IEnum getBizType() {
return AbssqrNoticeTypeEnum.BalanceCheck;
}
}
package com.abssqr.plat.biz.shared.scheduler.job.keeper.node;
import com.abssqr.plat.common.facade.enums.*;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.model.domain.plan.PlanTaskLog;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.repo.plan.PlanTaskLogRepo;
import com.abssqr.plat.core.service.acct.AcctManager;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.general.system.common.model.IEnum;
import com.general.system.common.model.Money;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.SystemDateUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* 每日十点放款池余额通知
*/
@Component
public class BalanceReportKeeper extends AbstractKeeperNode{
@Autowired
private PlanTaskLogRepo planTaskLogRepo;
@Autowired
private PlanRepo planRepo;
@Autowired
private AcctManager acctManager;
@Autowired
private WkPayManager wkPayManager;
@Value("${wkabs.zhaolian.balanceReport.deadline:10 0 0}")
private String deadline;
@Value("${wkabs.org.zhaolian:1009}")
private String zhaolianOrgCode;
@Override
protected Void doHandle(Date date) {
// 判断当前时间是否大于上午十点
Date currentTime = getCurrentStanderDate();
Date deadlineTime = getDeadLineTime(currentTime, deadline);
Map<String,Map<AccountAttributeEnum, Money>> buildMessageMap=new HashMap<>();
if (currentTime.compareTo(deadlineTime) >=0) {
LogUtil.info(LOGGER, "每日放款池余额通知-start");
Date bizDate =getCurrentStanderDate();
List<PlanTaskLog> tasks = planTaskLogRepo.getTasks(bizDate, PlanTaskTypeEnum.BALANCE_REPORT);
Map<String, List<PlanTaskLog>> planTaskLogMap = tasks.stream().collect(Collectors.groupingBy(PlanTaskLog::getPlanNo));
// 查询存续中的放款池计划
List<PlanBase> onGoingPlans = planRepo.getPlansByStatus(PlanTypeEnum.SPV, PlanStatusEnum.ONGOING);
for (PlanBase plan : onGoingPlans) {
boolean isExist=false;
if (tasks != null) {
isExist=planTaskLogMap.containsKey(plan.getPlanNo());
}
if (!isExist) {
Map<AccountAttributeEnum, Money> moneyMap = getMoneyMap(plan);
buildMessageMap.put(plan.getPlanNo(),moneyMap);
}else{
continue;
}
PlanTaskLog planTaskLog = new PlanTaskLog();
planTaskLog.setExecDate(bizDate);
planTaskLog.setPlanNo(plan.getPlanNo());
planTaskLog.setTaskType(PlanTaskTypeEnum.BALANCE_REPORT);
planTaskLogRepo.createTask(planTaskLog);
}
String reportMessage = buildReportMessage(buildMessageMap,date);
if (CollectionUtils.isNotEmpty(buildMessageMap.keySet())&&reportMessage.length() > 0) {
// 获取用户
Set<String> receivers = super.getAdminReceivers();
PlanBase planBase=new PlanBase();
super.sendBussinessNotice(planBase, zhaolianOrgCode, reportMessage, receivers);
}
}
LogUtil.info(LOGGER, "每日放款池余额通知-end");
return null;
}
private Map<AccountAttributeEnum,Money> getMoneyMap(PlanBase plan){
Map<AccountAttributeEnum,Money> accountAttributeEnumMoneyMap=new HashMap<>();
// 获取计划对应资金账户 平台虚拟户
List<Account> accounts = acctManager.getAcctByPlanNoAndType(plan.getPlanNo(), AccountTypeEnum.PLAT_VIRTUAL, false);
accounts.forEach(v->{
Money bankBal = new Money();
try {
// 调用外部接口查询账户余额
WkChannelNoEnum channelNo = WkChannelNoEnum.getPlatChannelNo(v.getChannelNo());
Money balance = wkPayManager.balance(v.getActNo(), channelNo);
if(balance!=null) {
bankBal.addTo(balance);
}
LogUtil.info(LOGGER, "{0}[{1}]查询账户余额: {2}", plan.getPlanType().getDesc(), plan.getPlanNo(), bankBal.getAmount());
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "[{0}]-ChannelNo[{1}]-ActNo[{2}]调用五矿查询账户余额异常",
plan.getPlanNo(), v.getChannelNo(), v.getActNo());
return;
}
accountAttributeEnumMoneyMap.put(v.getActAttr(),bankBal);
});
return accountAttributeEnumMoneyMap;
}
private String buildReportMessage(Map<String,Map<AccountAttributeEnum, Money>> buildMessageMap,Date currDate){
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currentTimeStr = sdf.format(currDate);
StringBuilder sb=new StringBuilder();
sb.append("截止到"+currentTimeStr+"\n");
buildMessageMap.forEach((planNo,moneyMap)->{
sb.append("放款池:"+planNo);
moneyMap.forEach((accountType,freeMoney)->{
switch (accountType) {
case RECV:{
sb.append("回款户余额为:"+freeMoney.getAmount());
break;
}
case PAY:{
sb.append("放款户余额为:"+freeMoney.getAmount());
break;
}
default:
throw new RuntimeException("不支持的账户类型:"+accountType);
}
sb.append("\n");
});
});
return sb.toString();
}
@Override
protected String getWatchJob() {
return null;
}
@Override
protected IEnum getBizType() {
return AbssqrNoticeTypeEnum.BalanceReport;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.keeper.node;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanCapitalOrderJob;
import com.abssqr.plat.common.facade.enums.AbssqrNoticeTypeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.general.system.common.model.IEnum;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Set;
/**
* 支付任务监控
*
* @author xiachenxiang
* @version com.abssqr.plat.biz.shared.scheduler.job.keeper.node: capitalOrderKeeper.java, v 0.1 2019-09-27 11:35 AM xiachenxiang Exp $
*/
@Component
public class CapitalOrderKeeper extends AbstractKeeperNode {
@Autowired
private PlanCapitalOrderRepo capitalOrderRepo;
@Value("${wkabs.org.zhaolian:1009}")
private String zhaolianOrgCode;
@Override
protected Void doHandle(Date date) {
LogUtil.info(LOGGER, "支付任务监控-start");
Long count = capitalOrderRepo.getFailCount(execTimes);
if (count != null && count > 0) {
String msg = MessageUtil.formatMsg("支付任务监控到有[{0}]条失败任务,请排查具体原因!", count);
LogUtil.info(LOGGER, msg);
// 获取用户
Set<String> receivers = super.getAdminReceivers();
super.sendSystemNotice("支付任务告警", zhaolianOrgCode, msg, receivers);
}
LogUtil.info(LOGGER, "支付任务监控-end");
return null;
}
@Override
protected IEnum getBizType() {
return AbssqrNoticeTypeEnum.CapitalOrder;
}
@Override
protected String getWatchJob() {
return PlanCapitalOrderJob.class.getName();
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.plan;
import cn.hutool.json.JSONUtil;
import com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.org.OrganizationEntity;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.model.enums.TraderTypeEnum;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.utils.DayUtil;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.acct.AcctManager;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.abssqr.plat.core.share.pay.PlanCapitalCreateRequest;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.general.system.common.model.Money;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.VarChecker;
import com.general.system.tool.util.ToolUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
import java.util.Optional;
/**
* 放款池计划 资金交易处理
* 放款截止日 次日进行 放款户向 回款户资金划账
*
* @author hanfei
* @version $Id: LenderOrgCapitalJob.java, v 0.1 2018-01-06 上午12:39 hanfei Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class LenderOrgCapitalJob extends BaseQuartzJob {
@Autowired
TransactionTemplate transactionTemplate;
@Autowired
WkPayManager wkPayManager;
@Autowired
PlanRepo planRepo;
@Autowired
AcctManager acctManager;
@Autowired
PlanAstManager planAstManager;
@Autowired
PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 每天 30 15/20 * * * ?
*/
@Value("${sync.quartz.plan.orgcapital}")
private String cron;
@Override
protected String getCronExpr() {
return cron;
}
@Override
protected boolean isRequestRecovery() {
return true;
}
@Override
public void doExecute() {
// 获取转让会计日
Day curDate = orgAcctDayComponent.getTrfAcctDay();
LogUtil.info(LOGGER, "[LnderOrgCapitalJob]-[{0}]放款计划资金交易处理-start", curDate);
// 1. 查询存续中的放款池计划
List<PlanBase> planBases = planRepo.getPlansByStatus(PlanTypeEnum.SPV, PlanStatusEnum.ONGOING);
for (PlanBase planBase : planBases) {
// 当前有资金交易单未处理完毕 则不进行账户资金处理等待下一次处理
// 校验是否需有未完成支付单
if (planCapitalOrderManager.repayAcctCapital(planBase.getPlanNo())){
continue;
}
if (!(planBase instanceof OrganizationEntity)){
LogUtil.error(LOGGER, "放款计划[{0}]模型不匹配", planBase);
}
OrganizationEntity entity = (OrganizationEntity)planBase;
if (ToolUtil.isEmpty(entity.getStopPayDate())){
continue;
}
final String planNo = entity.getPlanNo();
// 计算当前日期与 放款截止日相差天数
int count = DayUtil.diffDays(curDate, new Day(entity.getStopPayDate()));
try {
if (count >= 1) {
LogUtil.info(LOGGER, "放款计划[{0}]放款截止日次日资金交易处理开始", planNo);
// 放款截止日 次日进行 放款户向 回款户资金划账
this.execRemitRepo(curDate, entity);
LogUtil.info(LOGGER, "放款计划[{0}]放款截止日次日资金交易处理结束", planNo);
} else {
// 判断放款截止日 大于当前日期 不进行资金操作
LogUtil.info(LOGGER, "放款计划[{0}]非放款截止日次日, 当前时间为[{1}]", planNo,curDate);
continue;
}
} catch (AbssqrBizException e) {
if (CommonErrorCodeEnum.NO_DATA == e.getErrCode()) {
LogUtil.warn(LOGGER, e.getMessage());
} else {
LogUtil.error(LOGGER, e, "放款计划[{0}]放款截止日次日资金交易处理异常", entity);
}
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "放款计划[{0}]放款截止日次日资金交易处理异常", entity);
}
}
LogUtil.info(LOGGER, "[LenderOrgCapitalJob]-[{0}]放款计划资金交易处理-end", curDate.getStandardDate());
}
/**
* 放款户 转 回款户
*
* @param curDate
* @param entity
*/
private void execRemitRepo(Day curDate, OrganizationEntity entity) {
// 查询放款户余额
Money bankBal = new Money();
// 过滤出 放款户的平台虚拟账户
List<Account> accounts = acctManager.getAcctByPlanNoAndType(entity.getPlanNo(),
AccountTypeEnum.PLAT_VIRTUAL,false);
VarChecker.checkNotEmpty(accounts, "未找到对应的账号信息,[{0}]", entity.getPlanNo());
Optional<Account> platAcctOpt = accounts.stream()
.filter(item -> item.getActAttr() == AccountAttributeEnum.PAY)
.findFirst();
Account planAcct = platAcctOpt.get();
try {
// 3、调用外部接口查询账户余额
WkChannelNoEnum channelNo = WkChannelNoEnum.getPlatChannelNo(planAcct.getChannelNo());
bankBal.addTo(wkPayManager.balance(planAcct.getActNo(), channelNo));
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "查询[{0}]五矿账户余额异常", entity.getPlanNo());
throw e;
}
if (bankBal.isZero()) {
LogUtil.info(LOGGER, "放款计划[{0}]放款户余额为0 不做操作", entity.getPlanNo());
return;
}
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// 记录资产水位表 创建资金交易订单
planAstManager.changePlanAst(curDate.getStandardDate(), entity.getPlanNo(), (planAst, planAstLogList) -> {
boolean existCapital = planCapitalOrderManager.repayAcctCapital(entity.getPlanNo());
VarChecker.checkArgument(!existCapital,"回款户资金划账-未完成支付单,防止并发");
LogUtil.info(LOGGER, "放款计划[{0}]放款截止日次日进行放款户向回款户资金划账", entity.getPlanNo());
PlanCapitalTransTypeEnum transType = PlanCapitalTransTypeEnum.SPV_REMIT_REPO;
// 3、 创建支付订单
PlanCapitalCreateRequest request = new PlanCapitalCreateRequest();
request.setBizNo(SequenceUtil.genSeqNo(transType.getCode()));
request.setPlanNo(entity.getPlanNo());
request.setTargetOrgCode(entity.getPlanNo());
request.setTransAmt(bankBal);
request.setPayableAmt(bankBal);
request.setAccountDate(curDate.getStandardDate());
request.setTransType(transType);
request.setMemo("-放款截止日次日进行放款户向回款户资金划账");
PlanCapitalOrder order = planCapitalOrderManager.createCapitalOrder(request);
// 放款池放款终止转回款户 需要先增加校验金额 满足后续变更水位校验
planAstManager.changeCheckCashAmt(planAst, order.getTransAmt(), transType.getFlowType());
// 更新计划资产水位表,追加在途的支出收入金额,扣减待结算支出收入金额 并登记日志
planAstLogList.add(planAstManager.itemChangeStage(order.getAccountDate(), planAst, TraderTypeEnum.INITIATOR,
StageChangeTypeEnum.ON_WAY, order.getTransAmt(), transType,
order.getBizNo(), JSONUtil.toJsonStr(order)));
});
}
});
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.plan;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.general.system.common.util.LogUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.Date;
import java.util.List;
/**
* 承接池受让计划 与 放款池计划
* 结算单进行支付交易处理
三 增加清算支付处理任务 PlanAstClearingOrderHandler
1、拉取待支付的 结算单 TaskStatusEnum.INIT
2、根据对手机构进行汇总支付与收入,进行轧差计算,创建支付订单,一个对手机构对应一笔支付单
PlanCapitalTransTypeEnum 交易类型增加 支付 与 收入 类型进行对应
3、修改结算单状态为 WAITING,等待支付结果
4、变更资产水位表中待结算 与 在途金额
四 修改 PlanCapitalOrderListener 交易单结果监听器
1、增加选择处理器,根据不同 PlanCapitalTransTypeEnum 类型,进行对应业务处理剥离 分配兑付与清算
2、清算类型交易单结果处理:
2.1、拉取交易单据对应交易对手的结算单,根据实际确认金额,循环每条扣减金额及更改状态为SUCCESS
2.2、对支付金额不足剩余的 结算单 更改状态为 INIT,等待下次支付
2.3、根据交易单据金额更改扣减水位表的 待结算支出 或 待结算收入 金额
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.handler: PlanAstStatHandler.java, v 0.1 2019-06-12 20:44 zhenxuan.luo Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class PlanAstClearingOrderJob extends BaseQuartzJob {
@Autowired
private PlanRepo planRepo;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 每天 25 2/5 * * * ?
*/
@Value("${sync.quartz.plan.clear}")
private String cron;
@Override
protected String getCronExpr() {
return cron;
}
@Override
protected boolean isRequestRecovery() {
return true;
}
@Override
public void doExecute() {
// 获取转让会计日
Date curDate = orgAcctDayComponent.getTrfAcctDay().getStandardDate();
LogUtil.info(LOGGER, "[ClearingOrderJob]-[{0}]结算单进行支付交易处理任务start", curDate);
// 1.1 查询当前 状态为 存续中 承接池计划
List<PlanBase> onGoingPlans = planRepo.getPlansByStatus(null,PlanStatusEnum.ONGOING);
LogUtil.info(LOGGER, "[ClearingOrderJob]-当前存续期计划数量[{0}]", onGoingPlans.size());
for (PlanBase entity : onGoingPlans) {
final String planNo = entity.getPlanNo();
try {
LogUtil.info(LOGGER, "{0}[{1}]结算单进行支付交易处理开始", entity.getPlanType().getDesc(), planNo);
transactionTemplate.execute(status -> {
planAstClearingOrderHandler.handle(entity);
return null;
});
LogUtil.info(LOGGER, "{0}[{1}]结算单进行支付交易处理结束", entity.getPlanType().getDesc(), planNo);
} catch (AbssqrBizException e) {
if (CommonErrorCodeEnum.NO_DATA == e.getErrCode()) {
LogUtil.warn(LOGGER, e.getMessage());
} else {
LogUtil.error(LOGGER, e, "{0}[{1}]结算单进行支付交易处理异常", entity.getPlanType().getDesc(), planNo);
}
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "{0}[{1}]结算单进行支付交易处理异常", entity.getPlanType().getDesc(), planNo);
}
}
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.plan;
import com.abssqr.plat.biz.shared.handler.PlanAstStatTaskHandler;
import com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.general.system.common.util.LogUtil;
import com.general.system.tool.util.ToolUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.List;
/**
* 资产清算统计业务 初始化清算汇总调度任务
*
* @author hanfei
* @version $Id: PlanAstStatJob.java, v 0.1 2018-01-06 上午12:39 hanfei Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class PlanAstStatJob extends BaseQuartzJob {
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanAstStatTaskHandler planAstStatTaskHandler;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 每天 5 0/5 * * * ?
*/
@Value("${sync.quartz.plan.stat}")
private String cron;
@Override
protected String getCronExpr() {
return cron;
}
@Override
public void doExecute() {
// 获取转让会计日
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
LogUtil.info(LOGGER, "[PlanAstStatJob]-[{0}]资产清算统计业务start", trfDate.getDateString());
// 1.1 查询当前 状态为 存续中 承接池计划
List<PlanBase> onGoingPlans = planRepo.getPlansByStatus(null,PlanStatusEnum.ONGOING);
if (ToolUtil.isEmpty(onGoingPlans)){
return;
}
LogUtil.info(LOGGER, "[PlanAstStatJob]-当前存续期计划数量[{0}]", onGoingPlans.size());
for (PlanBase entity : onGoingPlans) {
final String planNo = entity.getPlanNo();
try {
LogUtil.info(LOGGER, "{0}[{1}]的统计任务初始化开始", entity.getPlanType().getDesc(), planNo);
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
PlanBase lockedPlanBase = planRepo.lockPlanByNo(planNo);
if (lockedPlanBase.getStatus() != PlanStatusEnum.ONGOING) {
LogUtil.info(LOGGER, "计划[{0}]不在存续期,不进行统计任务", lockedPlanBase);
return;
}
planAstStatTaskHandler.handle(lockedPlanBase.getPlanNo(), trfDate);
}
});
LogUtil.info(LOGGER, "{0}[{1}]的统计任务初始化结束", entity.getPlanType().getDesc(), planNo);
} catch (AbssqrBizException e) {
if (CommonErrorCodeEnum.NO_DATA == e.getErrCode()) {
LogUtil.warn(LOGGER, e.getMessage());
} else {
LogUtil.error(LOGGER, e, "{0}[{1}]的统计任务初始化异常", entity.getPlanType().getDesc(), planNo);
}
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "{0}[{1}]的统计任务初始化异常", entity.getPlanType().getDesc(), planNo);
}
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.plan;
import com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.PlanCapitalOrderDO;
import com.abssqr.plat.common.dal.mysql.auto.paging.PlanCapitalOrderPage;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.model.domain.job.JobControl;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.SystemDateUtil;
import com.general.system.common.util.ThreadUtil;
import com.general.system.tool.util.ToolUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
/**
* 计划资金支付交易单发起处理
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.scheduler.job.plan: PlanCapitalOrderJob.java, v 0.1 2019-06-18 21:19 zhenxuan
* .luo Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class PlanCapitalOrderJob extends BaseQuartzJob {
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private TransactionTemplate transactionTemplate;
/**
* 每天 30 3/5 * * * ?
*/
@Value("${sync.quartz.plan.capital}")
private String cron;
/**
* 每天 30 3/5 * * * ?
*/
@Value("${sync.space.capital:3000}")
private Long capital;
@Override
protected String getCronExpr() {
return cron;
}
@Override
protected boolean isRequestRecovery() {
return true;
}
@Override
public void doExecute() {
Date curExecTime = SystemDateUtil.getSystemDate();
// 获取 交易单据 改为查询 所有 init 状态的支付交易单 进行执行 使用分页查询减小外部并发
PlanCapitalOrderPage page = new PlanCapitalOrderPage();
page.setStatus(TaskStatusEnum.INIT.getCode());
page.setNextExecTime(curExecTime);
AtomicLong minId = new AtomicLong(0L);
do {
page.setId(minId.get());
// 1、查询资金单据
planCapitalOrderRepo.getCapitalOrderByStatus(page);
if (ToolUtil.isEmpty(page.getDatas())) {
LogUtil.info(LOGGER, "[CapitalOrderJob]-[{0}]资金支付交易单没有可执行数据", curExecTime);
return;
}
LogUtil.info(LOGGER, "[CapitalOrderJob]-[{0}]资金支付交易单发起处理任务start", curExecTime);
for (PlanCapitalOrderDO order : page.getDatas()) {
// 循环查询条件 设置最小id
minId.set( minId.get()<order.getId() ? order.getId() : minId.get());
try {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
// 交易单 加锁
PlanCapitalOrder lockOrdr = planCapitalOrderRepo.lockBySeqNo(order.getSeqNo());
// 执行时间判断
if (curExecTime.compareTo(lockOrdr.getProcTime()) >= 0) {
JobControl jobControl = jobControlRepository.selectByJobName(getJobName());
if (!jobControl.getIsEff().isYes()) {
LogUtil.warn(LOGGER, "计划资金单[{0}]终止,任务控制生效标记为[{1}]", getJobName(), jobControl.getIsEff());
return;
}
planCapitalOrderManager.processCapitalOrder(lockOrdr, SystemDateUtil.getSystemDate());
}
}
});
} catch (AbssqrBizException e) {
if (CommonErrorCodeEnum.NO_DATA == e.getErrCode()) {
LogUtil.warn(LOGGER, e.getMessage());
} else {
LogUtil.error(LOGGER, e, "计划资金单[{0}]发起交易异常:[{1}]", order.getSeqNo(), e.getMessage());
}
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "计划资金单[{0}]发起交易异常:[{1}]", order.getSeqNo(), e.getMessage());
}finally {
ThreadUtil.sleep(capital,LOGGER);
}
}
} while (page.hasNextPage());
LogUtil.info(LOGGER, "[CapitalOrderJob]-[{0}]资金支付交易单发起处理任务end:[{1}]", curExecTime, minId);
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.plan;
import com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.PlanCapitalOrderDO;
import com.abssqr.plat.common.dal.mysql.auto.paging.PlanCapitalOrderPage;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResultItem;
import com.abssqr.plat.common.model.convertor.PlanCapitalOrderConvertor;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.abssqr.plat.core.share.pay.PlanCapitalFinishRequest;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import com.general.system.common.model.Money;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.SystemDateUtil;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Maps;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;
/**
* 计划资金支付交易单结果查询
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.scheduler.job.plan: PlanCapitalOrderJob.java, v 0.1 2019-06-18 21:19 zhenxuan
* .luo Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class PlanCapitalOrderResJob extends BaseQuartzJob {
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private TransactionTemplate transactionTemplate;
@Autowired
private WkPayManager wkPayManager;
/**
* 每天 30 4/5 * * * ?
*/
@Value("${sync.quartz.plan.query}")
private String cron;
@Override
protected String getCronExpr() {
return cron;
}
@Override
protected boolean isRequestRecovery() {
return true;
}
/**
* 支付结果查询
* 1、查询资金单据 状态为 {@link TaskStatusEnum WAITING}
* 2、以 planCapitalOrder.getOutAcptNo() 对应 tradeNo 查询五矿订单结果接口
* 3、更新 资金单据 支付结果
*
* @throws JobExecutionException
*/
@Override
public void doExecute() {
Date curExecTime = SystemDateUtil.getSystemDate();
AtomicInteger count = new AtomicInteger();
PlanCapitalOrderPage page = new PlanCapitalOrderPage();
page.setNextExecTime(curExecTime);
page.setStatus(TaskStatusEnum.WAITING.getCode());
AtomicLong minId = new AtomicLong(0L);
do {
page.setId(minId.get());
// 1、查询资金单据
planCapitalOrderRepo.getCapitalOrderByStatus(page);
if (ToolUtil.isEmpty(page.getDatas())) {
LogUtil.info(LOGGER, "[CapitalOrderResJob]-[{0}]资金支付交易单没有可执行数据", curExecTime);
return;
}
LogUtil.info(LOGGER, "[CapitalOrderResJob]-[{0}]资金支付交易单结果查询任务start", curExecTime);
List<String> entryNos = new ArrayList<>(page.getDatas().size());
Map<String, PlanCapitalOrder> tradeMap = page.getDatas().stream().map(one -> {
entryNos.add(one.getOutAcptNo());
minId.set(minId.get()<one.getId()?one.getId():minId.get());
return one;
}).collect(Collectors
.toMap(PlanCapitalOrderDO::getOutAcptNo,
item -> PlanCapitalOrderConvertor.convert2Domain(item)));
LogUtil.info(LOGGER, "[CapitalOrderResJob]-[{0}]资金支付交易单结果查询任务-minId={1}", curExecTime, minId.get());
try {
// 2、查询五矿订单结果接口
TradeResult result = wkPayManager.tradeRstQry(entryNos);
final Map<String, TradeResultItem> enNoTradeMap = Maps.newHashMap();
if (ToolUtil.isNotEmpty(result.getPayInfoList())) {
enNoTradeMap.putAll(result.getPayInfoList().stream().collect(
Collectors.toMap(TradeResultItem::getEntryNo, tradeResultItem -> tradeResultItem)));
}
tradeMap.forEach((entryNo, order) -> {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
TradeResultItem item = enNoTradeMap.get(entryNo);
if (item == null) {
LogUtil.warn(LOGGER,"资金支付交易单结果查询-未查到条目号对应的结果,等待下次查询:{0}", entryNo);
} else {
PlanCapitalFinishRequest finishRequest = new PlanCapitalFinishRequest();
finishRequest.setSeqNo(order.getSeqNo());
finishRequest.setOutTransNo(item.getEntryNo());
finishRequest.setCfrmAmt(Money.createWithCent(item.getPayMoney()));
boolean isOver = false;
// 判断查询结果状态
switch (item.getStatus()) {
case 成功:
finishRequest.setRes(TaskStatusEnum.SUCCESS);
finishRequest.setMemo(item.getStatus().getDesc());
isOver = true;
break;
case 处理中:
// 处理中不做操作继续查询
break;
case 支付平台异常:
//什么都不做,发告警 fixme 发站内信,运营人员通知支付平台排查问题。
LogUtil.error(LOGGER,"支付平台异常-[{0}]",entryNo);
break;
default:
finishRequest.setRes(TaskStatusEnum.FAILURE);
finishRequest.setMemo(item.getStatus().getDesc());
isOver = true;
}
if (isOver) {
// 3、更新 资金单据 支付结果
planCapitalOrderManager.finishCapitalOrder(finishRequest);
}
}
count.getAndIncrement();
}
});
});
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "查询五矿订单结果接口异常:{0}", e.getMessage());
}
} while (page.hasNextPage());
LogUtil.info(LOGGER, "[CapitalOrderResJob]-[{0}]资金支付交易单结果查询任务end,exec[{1}]", curExecTime, count.get());
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.biz.shared.scheduler.job.plan;
import com.abssqr.plat.biz.shared.handler.PlanFundHandler;
import com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.general.system.common.util.LogUtil;
import com.general.system.tool.util.ToolUtil;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionException;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 资金到账情况查询
*
* @author bangis.wangdf
* @version com.abssqr.plat.biz.shared.scheduler.job.plan: PlanFundJob.java, v 0.1 2019-06-16 16:08 bangis.wangdf Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public class PlanFundJob extends BaseQuartzJob {
@Autowired
private PlanFundHandler planFundHandler;
@Autowired
private PlanRepo planRepo;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 每天 45 11/20 * * * ?
*/
@Value("${sync.quartz.plan.fund}")
private String cron;
@Override
protected String getCronExpr() {
return cron;
}
@Override
protected boolean isRequestRecovery() {
return true;
}
/**
* 计划银行账户余额查询
* 1、放款池回款户
* 2、受让池业务户
*
* @throws JobExecutionException
*/
@Override
public void doExecute() {
// 获取转让会计日
Day curDate = orgAcctDayComponent.getTrfAcctDay();
LogUtil.info(LOGGER, "[FundJob]-[{0}]余额查询任务start", curDate);
// 1.1 查询当前 状态为 存续中 承接池计划
List<PlanBase> onGoingPlans = planRepo.getPlansByStatus(null,PlanStatusEnum.ONGOING);
if (ToolUtil.isEmpty(onGoingPlans)){
return;
}
for (PlanBase entity : onGoingPlans) {
try {
// 执行余额查询
planFundHandler.executeQueryBalance(entity, curDate);
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "[FundJob]计划[{0}]余额修正任务异常", entity);
}
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.Result;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.domain.opr.OprRstHeader;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TradeList;
import com.abssqr.plat.common.integration.wk.domain.opr.response.AccountListResult;
import com.abssqr.plat.common.integration.wk.domain.opr.response.ProjectResult;
import com.abssqr.plat.common.integration.wk.domain.qry.QryRstHeader;
import com.abssqr.plat.common.integration.wk.domain.qry.response.BalanceResult;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
/**
* 五矿支付平台接口
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk: WkPayIntegration.java, v 0.1 2019-06-19 11:10 bangis.wangdf Exp $
*/
public interface WkPayIntegration {
/**
* 租户签约与维护
*
* @param seqNo 业务流水号,五矿使用UUID
* @return
*/
Result<OprRstHeader, ProjectResult> project(String seqNo,String projNo,String projName);
/**
* 账户信息维护
*
* @param seqNo
* @param accountList
* @return
*/
Result<OprRstHeader, AccountListResult> account(String seqNo, List<WkAccount> accountList);
/**
* 账户余额查询 B100002
* 最多50条
*
* @param seqNo
* @param no
* @return
*/
Result<QryRstHeader, BalanceResult> balance(String seqNo, String no, WkChannelNoEnum channelNo);
/**
* 代理交易
*
* @param seqNo
* @param tradeList
* @return
*/
Result<OprRstHeader, WkBody> trade(String seqNo, TradeList tradeList);
/**
* 代理交易结果查询
*
* @param seqNo
* @param entryNos
* @return
*/
Result<QryRstHeader, TradeResult> tradeRstQry(String seqNo, List<String> entryNos);
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain;
import javax.xml.bind.annotation.XmlRootElement;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: Request.java, v 0.1 2019-06-18 14:46 bangis.wangdf Exp $
*/
@XmlRootElement(name = "Package")
public class Request<H extends WkHeader, B extends WkBody> extends WkObject {
private H header;
private B body;
public H getHeader() {
return header;
}
public void setHeader(H header) {
this.header = header;
}
public B getBody() {
return body;
}
public void setBody(B body) {
this.body = body;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: Request.java, v 0.1 2019-06-18 14:46 bangis.wangdf Exp $
*/
public class Result<H extends WkHeader, B extends WkBody> extends WkObject {
private Class<H> headerClazz;
private Class<B> bodyClazz;
public Result(Class<H> headerClazz, Class<B> bodyClazz) {
this.headerClazz = headerClazz;
this.bodyClazz = bodyClazz;
}
private H header;
private B body;
public H getHeader() {
return header;
}
public void setHeader(H header) {
this.header = header;
}
public B getBody() {
return body;
}
public void setBody(B body) {
this.body = body;
}
public Class<H> getHeaderClazz() {
return headerClazz;
}
public Class<B> getBodyClazz() {
return bodyClazz;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: WkBody.java, v 0.1 2019-06-18 14:51 bangis.wangdf Exp $
*/
public class WkBody extends WkObject{
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain;
import java.util.Date;
import com.abssqr.plat.common.integration.wk.enums.WkAsynEnum;
import com.abssqr.plat.common.integration.wk.enums.ComIdEnum;
import com.abssqr.plat.common.integration.wk.enums.RequestTypeEnum;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: WkHeader.java, v 0.1 2019-06-18 14:47 bangis.wangdf Exp $
*/
public abstract class WkHeader extends WkObject {
/**
* 交易请求码
*/
private RequestTypeEnum RequestType;
/**
* 唯一编码
*/
private String UUID;
/**
* 业务系统标号
*/
private ComIdEnum comId;
/**
* 白名单ip地址
*/
private String comIP;
/**
* 请求发送时间
*/
private Date sendTime;
/**
* 是否异步接口
*/
private WkAsynEnum asyn;
/**
* 回调Url
*/
private String returnUrl;
/**
* 签名串
*/
private String signed;
/**
* 客户端 枚举 10 N
*/
private String clientType;
public RequestTypeEnum getRequestType() {
return RequestType;
}
public void setRequestType(RequestTypeEnum requestType) {
RequestType = requestType;
}
public String getUUID() {
return UUID;
}
public void setUUID(String UUID) {
this.UUID = UUID;
}
public ComIdEnum getComId() {
return comId;
}
public void setComId(ComIdEnum comId) {
this.comId = comId;
}
public String getComIP() {
return comIP;
}
public void setComIP(String comIP) {
this.comIP = comIP;
}
public Date getSendTime() {
return sendTime;
}
public void setSendTime(Date sendTime) {
this.sendTime = sendTime;
}
public WkAsynEnum getAsyn() {
return asyn;
}
public void setAsyn(WkAsynEnum asyn) {
this.asyn = asyn;
}
public String getReturnUrl() {
return returnUrl;
}
public void setReturnUrl(String returnUrl) {
this.returnUrl = returnUrl;
}
public String getSigned() {
return signed;
}
public void setSigned(String signed) {
this.signed = signed;
}
public String getClientType() {
return clientType;
}
public void setClientType(String clientType) {
this.clientType = clientType;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: WkObject.java, v 0.1 2019-06-18 17:41 bangis.wangdf Exp $
*/
public abstract class WkObject {
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
/**
* @see java.lang.Object#clone()
*/
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: WkPayConfig.java, v 0.1 2019-06-19 19:00 bangis.wangdf Exp $
*/
@Component
@ConfigurationProperties(prefix = "wkabs.pay")
public class WkPayConfig {
/**
* 项目编号
*/
private String projNo;
/**
* 项目名称
*/
private String projName;
/**
* 余额类型(
* 本地("0", "本地"),
* 渠道余额("1", "渠道余额"),)
*/
private String balanceType;
/**
* 交易代理结果回调
*/
private String tradeCallBackUrl;
/**
* 五矿支付wsdl地址
*/
private String host;
public String getProjNo() {
return projNo;
}
public void setProjNo(String projNo) {
this.projNo = projNo;
}
public String getProjName() {
return projName;
}
public void setProjName(String projName) {
this.projName = projName;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getTradeCallBackUrl() {
return tradeCallBackUrl;
}
public void setTradeCallBackUrl(String tradeCallBackUrl) {
this.tradeCallBackUrl = tradeCallBackUrl;
}
public String getBalanceType() {
return balanceType;
}
public void setBalanceType(String balanceType) {
this.balanceType = balanceType;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.config;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.io.IoUtil;
import com.abssqr.gateway.util.SftpUtil;
import com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.utils.SftpFileUtil;
import com.jcraft.jsch.ChannelSftp;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.InputStream;
/**
* sftp 配置
* @author hanfei
* @version $Id: WkSftpConfig.java, v 0.1 2019-09-19 4:23 PM hanfei Exp $
*/
@Component
@ConfigurationProperties(prefix = "wkabs.upload")
public class WkSftpConfig {
private static ThreadLocal<SftpFileUtil> selfChannelSftpThreadLocal = new ThreadLocal<>();
/**
* sftp 下载
*/
public FastByteArrayOutputStream downloadSftp(String fileSrc){
try {
InputStream stream = SftpUtil.getInputStream(fileSrc, this.selfChannelSftp());
return IoUtil.read(stream);
} catch (Exception e) {
throw new AbssqrBizException("下载文件异常", CommonErrorCodeEnum.SFTP_ERROR, e);
} finally {
close();
}
}
/**
* sftp 上传
*/
public boolean uploadSftp(InputStream stream, String fileName, String filePath){
try {
boolean result = SftpUtil.uploadFile(filePath, fileName, stream, this.selfChannelSftp());
if (!result){
throw new AbssqrBizException("上传文件失败", CommonErrorCodeEnum.SFTP_ERROR);
}
return result;
} catch (Exception e) {
throw new AbssqrBizException("上传文件异常", CommonErrorCodeEnum.SFTP_ERROR, e);
} finally {
close();
}
}
/**
* 获取sftp 连接通道
* @return
*/
public ChannelSftp selfChannelSftp() {
if (selfChannelSftpThreadLocal.get() == null) {
SftpFileUtil _sftpFileUtil = new SftpFileUtil(
this.getHost(),
this.getPort(),
this.getUsername(),
this.getPassword());
selfChannelSftpThreadLocal.set(_sftpFileUtil);
}
return selfChannelSftpThreadLocal.get().getChannel();
}
/**
* 关闭连接通道
*/
public static void close() {
if (selfChannelSftpThreadLocal.get() != null) {
selfChannelSftpThreadLocal.get().close();
selfChannelSftpThreadLocal.set(null);
}
}
/**
* 上传方式
*/
private String type;
/**
* 地址
*/
private String host;
/**
* 端口
*/
private Integer port;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 超时时间
*/
private String timeout;
/**
* 上传路径
*/
private String path;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTimeout() {
return timeout;
}
public void setTimeout(String timeout) {
this.timeout = timeout;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr;
import com.abssqr.plat.common.integration.wk.domain.WkHeader;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.ws: OprHeader.java, v 0.1 2019-06-18 14:02 bangis.wangdf Exp $
*/
public class OprHeader extends WkHeader {
/**
* 交易数量
*/
private int tradeCount;
public int getTradeCount() {
return tradeCount;
}
public void setTradeCount(int tradeCount) {
this.tradeCount = tradeCount;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr;
import com.abssqr.plat.common.integration.wk.domain.WkHeader;
import com.abssqr.plat.common.integration.wk.enums.ComIdEnum;
import com.abssqr.plat.common.integration.wk.enums.PlatResultCodeEnum;
import com.abssqr.plat.common.integration.wk.enums.RequestTypeEnum;
import java.util.Date;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.ws: OprRstHeader.java, v 0.1 2019-06-18 14:24 bangis.wangdf Exp $
*/
public class OprRstHeader extends WkHeader {
/**
* 返回状态 10000 成功 90000 支付平台异常
*/
private PlatResultCodeEnum resultCode;
/**
* 返回信息描述
*/
private String resultMsg;
public PlatResultCodeEnum getResultCode() {
return resultCode;
}
public void setResultCode(PlatResultCodeEnum resultCode) {
this.resultCode = resultCode;
}
public String getResultMsg() {
return resultMsg;
}
public void setResultMsg(String resultMsg) {
this.resultMsg = resultMsg;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.enums.ProjStateEnum;
/**
* 3.2.13租户信息维护
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request: Project.java, v 0.1 2019-06-19 10:54 bangis
* .wangdf Exp $
*/
@XmlRootElement(name = "ProjectCreate")
public class Project extends WkBody {
/**
* 租户号
*/
private String projNo;
/**
* 租户名称
*/
private String projName;
/**
* 租户状态 字符 2 Y 01-生效,02-失效
*/
private ProjStateEnum ProjState;
/**
* 保留域
*/
private String info1;
public String getProjNo() {
return projNo;
}
public void setProjNo(String projNo) {
this.projNo = projNo;
}
public String getProjName() {
return projName;
}
public void setProjName(String projName) {
this.projName = projName;
}
public ProjStateEnum getProjState() {
return ProjState;
}
public void setProjState(ProjStateEnum projState) {
ProjState = projState;
}
public String getInfo1() {
return info1;
}
public void setInfo1(String info1) {
this.info1 = info1;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.acct;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
/**
* 账户列表
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request: AccountList.java, v 0.1 2019-06-19 18:41 bangis.wangdf Exp $
*/
public class AccountList extends WkBody {
List<WkAccount> accountList;
public List<WkAccount> getAccountList() {
return accountList;
}
public void setAccountList(List<WkAccount> accountList) {
this.accountList = accountList;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.acct;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkAcctKindEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAcctTypeEnum;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil.Account;
import javax.xml.bind.annotation.XmlRootElement;
/**
* 账户信息
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request: WkAccount.java, v 0.1 2019-06-19 18:42 bangis
* .wangdf Exp $
*/
@XmlRootElement(name = "AccountInfo")
public class WkAccount extends WkObject {
/**
AccountNo 账户号 字符 32 Y 不能使用ufc(不区分大小写)开头,业务系统保证唯一并以业务系统编号开头,且只能由数字、字母和下划线组成
AccountName 账户名称 字符 128 N 非空时使用
TenantNo 租户编号 字符 32 Y 支付平台开通的租户编号,使用前向支付平台获取,一旦与账户绑定成功后无法修改
CustNo 客户号/用户号 字符 64 N 不能使用ufc(不区分大小写)开头,业务系统保证唯一,且只能由数字、字母和下划线组成
CustName 客户名称/用户名称 字符 128 N 非空时使用
AcctType 账户类型 字符 2 Y 1-放款账户,2-扣款账户,3-商户账户,4-费用账户,5-溢缴款账户
AcctKind 账户种类 字符 2 N 非必填,为空的情况下为 对私,指定了 账户种类 之后,按照指定的 类型进行建立。
01为对公,02为对私
*/
/**
* @see Account#genAccountNo(com.abssqr.plat.common.integration.wk.enums.TradeTypeEnum, java.lang.String, com.abssqr.plat.common.facade.enums.AccountAttributeEnum)
* 不能使用ufc(不区分大小写)开头,业务系统保证唯一并以业务系统编号开头,且只能由数字、字母和下划线组成
* 000004_TradeTypeEnum_planNo
*/
private String accountNo;
/**
* @see Account#genAccountName(com.abssqr.plat.common.integration.wk.enums.TradeTypeEnum, java.lang.String, com.abssqr.plat.common.facade.enums.AccountAttributeEnum)
* 不能使用ufc(不区分大小写)开头,业务系统保证唯一并以业务系统编号开头,且只能由数字、字母和下划线组成
* 000004_扣款/放款_planName
*/
private String accountName;
/**
* 租户编号 之前生成的租户编号
*/
private String tenantNo;
/**
* @see WkSequenceUtil.Account#genCustNo(String)
* 客户号,使用计划编号
* 000004_planNo
*/
private String custNo;
/**
* @see WkSequenceUtil.Account#genCustName(String)
* 客户名称 计划名称
*/
private String custName;
/**
* 账户类型 字符 2 Y 1-放款账户,2-扣款账户,3-商户账户,4-费用账户,5-溢缴款账户
*/
private WkAcctTypeEnum acctType;
/**
* 账户种类 字符 2 N 非必填,为空的情况下为 对私,指定了 账户种类 之后,按照指定的 类型进行建立。
* 01为对公,02为对私
*/
private WkAcctKindEnum acctKind;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public String getTenantNo() {
return tenantNo;
}
public void setTenantNo(String tenantNo) {
this.tenantNo = tenantNo;
}
public String getCustNo() {
return custNo;
}
public void setCustNo(String custNo) {
this.custNo = custNo;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public WkAcctTypeEnum getAcctType() {
return acctType;
}
public void setAcctType(WkAcctTypeEnum acctType) {
this.acctType = acctType;
}
public WkAcctKindEnum getAcctKind() {
return acctKind;
}
public void setAcctKind(WkAcctKindEnum acctKind) {
this.acctKind = acctKind;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.trade;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkAccountTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request.trade: TdAccountInfo.java, v 0.1 2019-06-20 20:51
* bangis.wangdf Exp $
*/
@XmlRootElement(name = "AccountInfo")
public class TdAccountInfo extends WkObject {
/**
* 账户号 字符 32 Y 银行账户号或支付平台账户号
**/
private String accountNo;
/**
* 账户类型 枚举 2 Y 详见4.7
**/
private WkAccountTypeEnum accountType;
/**
* 账户姓名 字符 64 S 账户姓名,使用银行账户时非空
**/
private String accountName;
/**
* 支付系统渠道(银行)编号 枚举 10 S 见4.3渠道代码列表,使用客户银行账户时非空
**/
private WkChannelNoEnum channelNo;
/**
* 联行号 枚举 20 S 联行号,暂时未使用
**/
private String bankDetailNo;
/**
* 开户行名称 字符 128 S 网点/支行名称 当账户类型为企业账户时该项必填
**/
private String bankName;
/**
* 开户行所在省 字符 128 S 网点/支行所在省 当账户类型为企业账户时该项必填
**/
private String province;
/**
* 开户行所在市 字符 128 S 网点/支行所在市 当账户类型为企业账户时该项必填
**/
private String city;
/**
* 信用卡3位安全码 字符 3 S 信用卡3位安全码 账户类型为个人信用卡必填
**/
private String CVN2;
/**
* 信用卡有效期 字符 4 S 格式 YYMM 账户类型为个人信用卡必填
**/
private String VALDATE;
/**
* 手机号 字符 15 N 手机号
**/
private String phoneNo;
/**
* email 字符 20 N email
**/
private String Email;
/**
* 证件类型 字符 5 Y 见4.6目前仅支持身份证
* 0 个人 身份证
* 1 个人 户口簿
* 2 个人 护照
* 3 个人 军官证
* 4 个人 士兵证
* 5 个人 港澳居民来往内地通行证
* 6 个人 台湾同胞来往内地通行证
* 7 个人 临时身份证
* 8 个人 外国人居留证
* 9 个人 警官证
* X 个人/企业 其他证件
* A 企业 组织机构代码证号
* B 企业 营业执照号码
* C 企业 登记证书
* D 企业 国税登记证号码
* E 企业 地税登记证号码
* F 企业 开户许可证
* G 企业 事业单位编号
* I 企业 金融许可证编号
**/
private String certificateType;
/**
* 证件号 字符 20 Y 证件号
**/
private String certificateNo;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public WkAccountTypeEnum getAccountType() {
return accountType;
}
public void setAccountType(WkAccountTypeEnum accountType) {
this.accountType = accountType;
}
public String getAccountName() {
return accountName;
}
public void setAccountName(String accountName) {
this.accountName = accountName;
}
public WkChannelNoEnum getChannelNo() {
return channelNo;
}
public void setChannelNo(WkChannelNoEnum channelNo) {
this.channelNo = channelNo;
}
public String getBankDetailNo() {
return bankDetailNo;
}
public void setBankDetailNo(String bankDetailNo) {
this.bankDetailNo = bankDetailNo;
}
public String getBankName() {
return bankName;
}
public void setBankName(String bankName) {
this.bankName = bankName;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCVN2() {
return CVN2;
}
public void setCVN2(String CVN2) {
this.CVN2 = CVN2;
}
public String getVALDATE() {
return VALDATE;
}
public void setVALDATE(String VALDATE) {
this.VALDATE = VALDATE;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public String getCertificateType() {
return certificateType;
}
public void setCertificateType(String certificateType) {
this.certificateType = certificateType;
}
public String getCertificateNo() {
return certificateNo;
}
public void setCertificateNo(String certificateNo) {
this.certificateNo = certificateNo;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.trade;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.enums.EnTradeTypeEnum;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil.Trade;
/**
* 交易详情
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request: TdEntryInfo.java, v 0.1 2019-06-20 20:19 bangis
* .wangdf Exp $
*/
@XmlRootElement(name = "EntryInfo")
public class TdEntryInfo extends WkObject {
/**
EntryNo 条目号 字符 50 Y 业务系统保证唯一,并以业务系统编号开头
EnTradeType 条目交易类型 枚举 2 Y 详见4.4
Amount 金额 金钱 10 Y 交易金额(单位:分)
EntryTypeNo 条目类型编号 数字 10 Y 最大长度10位数字
须由交易类型编号开头
统一交易内编号长度必须一致,统一交易编号补不能重复
(交易优先级按照条目类型编号,由小到大)
ChannelNo 渠道编号 字符 6 S 指定渠道,选填,如果有效则直接使用指定渠道而不路由,如果无效则直接失败。
SourceAccountList 源交易账户信息列表 列表 Y 列表内容为SourceAccountInfo,不同交易对列表数量要求不同,详见4.4 根据扣款放款转换
TargetAccountList 目标交易账户信息列表 列表 Y 列表内容为 TargetAccountInfo,不同交易对列表数量要求不同,详见4.4
Remark1 备注1 字符 128 N 备注1
Remark2 备注2 字符 128 N 备注2
Remark3 备注3 字符 128 N 备注3
*/
/**
* @see Trade#genEntryNo()
* 条目号 字符 50 Y 业务系统保证唯一,并以业务系统编号开头
*/
private String entryNo;
/**
* 条目交易类型 枚举 2 Y 详见4.4
*/
private EnTradeTypeEnum enTradeType;
/**
* 金额 金钱 10 Y 交易金额(单位:分)
*/
private long amount;
/**
* @see Trade#genEntryTypeNo(EnTradeTypeEnum, int)
* 条目类型编号 数字 10 Y 最大长度10位数字
* 须由交易类型编号开头
* 统一交易内编号长度必须一致,统一交易编号补不能重复
* (交易优先级按照条目类型编号,由小到大)
*/
private String entryTypeNo;
/**
* 渠道编号 字符 6 S 指定渠道,选填,如果有效则直接使用指定渠道而不路由,如果无效则直接失败。
*/
private WkChannelNoEnum channelNo;
/**
* 源交易账户信息列表 列表 Y 列表内容为SourceAccountInfo,不同交易对列表数量要求不同,详见4.4 根据扣款放款转换
*/
private List<TdSourceAccountInfo> sourceAccountList;
/**
* TargetAccountList 目标交易账户信息列表 列表 Y 列表内容为 TargetAccountInfo,不同交易对列表数量要求不同,详见4.4
*/
private List<TdTargetAccountInfo> targetAccountList;
private String remark1;
private String remark2;
private String remark3;
public String getEntryNo() {
return entryNo;
}
public void setEntryNo(String entryNo) {
this.entryNo = entryNo;
}
public EnTradeTypeEnum getEnTradeType() {
return enTradeType;
}
public void setEnTradeType(EnTradeTypeEnum enTradeType) {
this.enTradeType = enTradeType;
}
public long getAmount() {
return amount;
}
public void setAmount(long amount) {
this.amount = amount;
}
public String getEntryTypeNo() {
return entryTypeNo;
}
public void setEntryTypeNo(String entryTypeNo) {
this.entryTypeNo = entryTypeNo;
}
public WkChannelNoEnum getChannelNo() {
return channelNo;
}
public void setChannelNo(WkChannelNoEnum channelNo) {
this.channelNo = channelNo;
}
public List<TdSourceAccountInfo> getSourceAccountList() {
return sourceAccountList;
}
public void setSourceAccountList(List<TdSourceAccountInfo> sourceAccountList) {
this.sourceAccountList = sourceAccountList;
}
public List<TdTargetAccountInfo> getTargetAccountList() {
return targetAccountList;
}
public void setTargetAccountList(List<TdTargetAccountInfo> targetAccountList) {
this.targetAccountList = targetAccountList;
}
public String getRemark1() {
return remark1;
}
public void setRemark1(String remark1) {
this.remark1 = remark1;
}
public String getRemark2() {
return remark2;
}
public void setRemark2(String remark2) {
this.remark2 = remark2;
}
public String getRemark3() {
return remark3;
}
public void setRemark3(String remark3) {
this.remark3 = remark3;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.trade;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request.trade: TdSourceAccountInfo.java, v 0.1 2019-06-20 20:48 bangis.wangdf Exp $
*/
@XmlRootElement(name = "SourceAccountInfo")
public class TdSourceAccountInfo extends WkObject {
/**
* 账户信息
*/
private TdAccountInfo accountInfo;
/**
* 优先级,如果有多个交易账号时需要通过优先级指定使用顺序(同一条目内不能重复),按从小到大使用,长度固定2
*/
private int level;
public TdAccountInfo getAccountInfo() {
return accountInfo;
}
public void setAccountInfo(TdAccountInfo accountInfo) {
this.accountInfo = accountInfo;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.trade;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request.trade: TdSourceAccountInfo.java, v 0.1 2019-06-20 20:48 bangis.wangdf Exp $
*/
@XmlRootElement(name = "TargetAccountInfo")
public class TdTargetAccountInfo extends WkObject {
/**
* 账户信息
*/
private TdAccountInfo accountInfo;
/**
* 优先级,如果有多个交易账号时需要通过优先级指定使用顺序(同一条目内不能重复),按从小到大使用,长度固定2
*/
private int level;
public TdAccountInfo getAccountInfo() {
return accountInfo;
}
public void setAccountInfo(TdAccountInfo accountInfo) {
this.accountInfo = accountInfo;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.trade;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.TradeTypeEnum;
/**
* 交易信息
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request: TradeInfo.java, v 0.1 2019-06-20 20:15 bangis
* .wangdf Exp $
*/
public class TradeInfo extends WkObject {
/**
* TradeNo 交易号 字符 50 Y 业务系统保证唯一,并以业务系统编号开头
* TradeTypeNo 交易类型编号 数字 6 Y 最大长度6位数字 001放,002扣款
* TotalEntryNum 总条目数 字符 2 Y 最大10(同一交易最多10个条目)
* EntryList 交易详情 列表 Y 列表内容为 TdEntryInfo
*/
/**
*
* 交易号 字符 50 Y 业务系统保证唯一,并以业务系统编号开头
*/
private String tradeNo;
/**
* 交易类型编号 数字 6 Y 最大长度6位数字 001放,002扣款
*/
private TradeTypeEnum tradeTypeNo;
/**
* 总条目数 字符 2 Y 最大10(同一交易最多10个条目)
*/
private Long totalEntryNum;
/**
* 交易详情 列表 Y 列表内容为 TdEntryInfo
*/
private List<TdEntryInfo> entryList;
public String getTradeNo() {
return tradeNo;
}
public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
}
public TradeTypeEnum getTradeTypeNo() {
return tradeTypeNo;
}
public void setTradeTypeNo(TradeTypeEnum tradeTypeNo) {
this.tradeTypeNo = tradeTypeNo;
}
public Long getTotalEntryNum() {
if(totalEntryNum==null&&this.entryList!=null){
return Long.valueOf(this.entryList.size());
}
return totalEntryNum;
}
public void setTotalEntryNum(Long totalEntryNum) {
this.totalEntryNum = totalEntryNum;
}
public List<TdEntryInfo> getEntryList() {
return entryList;
}
public void setEntryList(List<TdEntryInfo> entryList) {
this.entryList = entryList;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.request.trade;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
/**
* 代理交易
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.request: TradeList.java, v 0.1 2019-06-20 20:12 bangis
* .wangdf Exp $
*/
public class TradeList extends WkBody {
private List<TradeInfo> tradeList;
public List<TradeInfo> getTradeList() {
return tradeList;
}
public void setTradeList(List<TradeInfo> tradeList) {
this.tradeList = tradeList;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.response;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.response: AccountListResult.java, v 0.1 2019-06-19 19:17
* bangis.wangdf Exp $
*/
public class AccountListResult extends WkBody {
List<AccountResult> accountList;
public List<AccountResult> getAccountList() {
return accountList;
}
public void setAccountList(
List<AccountResult> accountList) {
this.accountList = accountList;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.response;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkAcctStatusEnum;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.response: AccountResult.java, v 0.1 2019-06-19 19:17
* bangis.wangdf Exp $
*/
@XmlRootElement(name = "AccountInfo")
public class AccountResult extends WkObject {
/**
* AccountNo 账户号 字符 64 Y 不能使用ufc(不区分大小写)开头,业务系统保证唯一并以业务系统编号开头
* Status 交易状态 枚举 2 Y 见4.5
* Message 信息描述 字符 128 Y
*/
private String accountNo;
/**
* 交易状态
*/
private WkAcctStatusEnum status;
/**
* 信息描述
*/
private String message;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public WkAcctStatusEnum getStatus() {
return status;
}
public void setStatus(WkAcctStatusEnum status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.opr.response;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.enums.WkResultCodeEnum;
/**
* 3.2.13租户信息维护结果
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.opr.response: ProjectResult.java, v 0.1 2019-06-19 11:04
* bangis.wangdf Exp $
*/
@XmlRootElement(name = "ProjectCreateResult")
public class ProjectResult extends WkBody {
/**
* 信息维护结果
*/
private WkResultCodeEnum resultCode;
/**
* 信息维护结果描述
*/
private String resultDesc;
public WkResultCodeEnum getResultCode() {
return resultCode;
}
public void setResultCode(WkResultCodeEnum resultCode) {
this.resultCode = resultCode;
}
public String getResultDesc() {
return resultDesc;
}
public void setResultDesc(String resultDesc) {
this.resultDesc = resultDesc;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry;
import com.abssqr.plat.common.integration.wk.domain.WkHeader;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: QryHeader.java, v 0.1 2019-06-18 14:24 bangis.wangdf Exp $
*/
public class QryHeader extends WkHeader {
/**
* 每页条数
*/
private int PageSize;
/**
* 页码
*/
private int PageNo;
public int getPageSize() {
return PageSize;
}
public void setPageSize(int pageSize) {
PageSize = pageSize;
}
public int getPageNo() {
return PageNo;
}
public void setPageNo(int pageNo) {
PageNo = pageNo;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry;
import com.abssqr.plat.common.integration.wk.domain.WkHeader;
import com.abssqr.plat.common.integration.wk.domain.opr.OprRstHeader;
import com.abssqr.plat.common.integration.wk.enums.ComIdEnum;
import com.abssqr.plat.common.integration.wk.enums.PlatResultCodeEnum;
import com.abssqr.plat.common.integration.wk.enums.RequestTypeEnum;
import javax.xml.crypto.Data;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain: QryRstHeader.java, v 0.1 2019-06-18 14:25 bangis.wangdf Exp $
*/
public class QryRstHeader extends OprRstHeader {
/**
* 最大页码
*/
private int maxPage;
public int getMaxPage() {
return maxPage;
}
public void setMaxPage(int maxPage) {
this.maxPage = maxPage;
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry;
/**
*
* @author yangcheng
* @version TradeItem.java, v0.12019-06-1816:43 yangchengExp$
*/
public class QueryInfo {
/**
* 查询条件 编号
*/
private String no;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.request;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.enums.LocalOrChannelEnum;
/**
*账户余额查询接口请求
*
* @author yangcheng
* @version AccountBalanceParam.java, v0.12019-06-1815:52 yangchengExp$
*/
public class AccountBalanceParam extends WkBody {
/**
* 账户号
*/
private String no;
/*
* 渠道代码
*/
private WkChannelNoEnum channelNo;
/**
* 本地或渠道余额 0-本地,1-渠道余额
*/
private LocalOrChannelEnum localOrChannel;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public WkChannelNoEnum getChannelNo() {
return channelNo;
}
public void setChannelNo(WkChannelNoEnum channelNo) {
this.channelNo = channelNo;
}
public LocalOrChannelEnum getLocalOrChannel() {
return localOrChannel;
}
public void setLocalOrChannel(LocalOrChannelEnum localOrChannel) {
this.localOrChannel = localOrChannel;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.request.trade;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.qry.request.trade: TradeItem.java, v 0.1 2019-06-21 21:29
* bangis.wangdf Exp $
*/
@XmlRootElement(name = "QueryInfo")
public class TradeItem extends WkObject {
/**
* 查询条件 编号
*/
private String no;
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.request.trade;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.enums.TradeQueryTypeEnum;
/**
* 交易结果查询
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.qry.request.trade: TradeQuery.java, v 0.1 2019-06-21 21:23
* bangis.wangdf Exp $
*/
public class TradeQuery extends WkBody {
/**
QueryType 查询类型 字符 2 Y 1 按日期区间查询
2 按接口流水号查询
3按交易交易号查询
4按交易条目号查询
StartDate 开始日期 枚举 10 S “查询类型”为1时必传
格式:yyyy-MM-dd
EndDate 结束日期 枚举 10 S “查询类型”为1时必传
格式:yyyy-MM-dd
QueryList 查询条件 列表 S “查询类型”为2、3、4时必传,列表内容为 TradeItem,
一次请求最多50个查询条件
*/
/**
* 查询类型
*/
private TradeQueryTypeEnum queryType;
private String startDate;
private String endDate;
private List<TradeItem> queryList;
public TradeQueryTypeEnum getQueryType() {
return queryType;
}
public void setQueryType(TradeQueryTypeEnum queryType) {
this.queryType = queryType;
}
public String getStartDate() {
return startDate;
}
public void setStartDate(String startDate) {
this.startDate = startDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
public List<TradeItem> getQueryList() {
return queryList;
}
public void setQueryList(List<TradeItem> queryList) {
this.queryList = queryList;
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.response;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
/**
*账户余额明细响应
* @author yangcheng
* @version BalanceInfo.java, v0.12019-06-1816:20 yangchengExp$
*/
public class BalanceInfo extends WkObject {
/**
* 账户号
*/
private String accountNo;
/**
* 渠道编号
*/
private WkChannelNoEnum channelNo;
/**
* 余额
*/
private long balance;
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public WkChannelNoEnum getChannelNo() {
return channelNo;
}
public void setChannelNo(WkChannelNoEnum channelNo) {
this.channelNo = channelNo;
}
public long getBalance() {
return balance;
}
public void setBalance(long balance) {
this.balance = balance;
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.response;
import java.util.List;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
/**
* @author yangcheng
* @version BalanceResult.java, v0.12019-06-1816:26 yangchengExp$
*/
public class BalanceResult extends WkBody {
private List<BalanceInfo> balanceList;
public List<BalanceInfo> getBalanceList() {
return balanceList;
}
public void setBalanceList(List<BalanceInfo> balanceList) {
this.balanceList = balanceList;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.response.trade;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.enums.WkTradeStatusEnum;
import com.general.system.tool.util.ToolUtil;
import java.util.ArrayList;
import java.util.List;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.qry.response.trade: TradeResult.java, v 0.1 2019-06-21 21:36
* bangis.wangdf Exp $
*/
public class TradeResult extends WkBody {
List<TradeResultItem> payInfoList;
public List<TradeResultItem> getPayInfoList() {
return payInfoList;
}
public void setPayInfoList(
List<TradeResultItem> payInfoList) {
this.payInfoList = payInfoList;
}
public static List<TradeResultItem> mockDate(List<PlanCapitalOrder> orders){
List<TradeResultItem> list = new ArrayList<>();
if (ToolUtil.isEmpty(orders)){
return list;
}
orders.forEach(one -> {
TradeResultItem item = new TradeResultItem();
item.setEntryNo(one.getOutAcptNo());
item.setPayMoney(one.getTransAmt().getCent());
item.setStatus(WkTradeStatusEnum.成功);
list.add(item);
});
return list;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.domain.qry.response.trade;
import java.util.Date;
import javax.xml.bind.annotation.XmlRootElement;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.enums.EnTradeTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkTradeStatusEnum;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.domain.qry.response.trade: TradeResultItem.java, v 0.1 2019-06-21
* 21:37 bangis.wangdf Exp $
*/
@XmlRootElement(name = "PayInfo")
public class TradeResultItem extends WkObject {
/**
FlowNo 接口流水号 枚举 32 Y 头报文UUID
TradeNo 交易号 字符 32 Y
TradeTypeNo 交易业务类型 字符 10 Y
TradeChannel 交易渠道 枚举 8 Y 4.3渠道代码表
EntryNo 条目号 字符 32 Y
EntryTypeNo 条目业务类型 金额 10 Y
RpayMoney 请求支付金额 字符 10 Y (单位分)
PayMoney 实际支付金额 字符 10 Y (单位分)
EnTradeType 条目交易类型 枚举 2 Y 见4.4
PayTime 交易时间 字符 20 Y yyyy-MM-dd HH:mm:ss
Status 交易状态 字符 2 Y 见4.5
Message 交易信息反馈 字符 128 Y
*/
/**
* 接口流水号 枚举 32 Y 头报文UUID
*/
private String flowNo;
/**
* 交易号 字符 32 Y
*/
private String tradeNo;
/**
* 交易业务类型 字符 10 Y
*/
private String tradeTypeNo;
/**
* 交易渠道 枚举 8 Y 4.3渠道代码表
*/
private WkChannelNoEnum tradeChannel;
/**
* 条目号 字符 50 Y 业务系统保证唯一,并以业务系统编号开头
*/
private String entryNo;
/**
* 请求支付金额 Y 交易金额(单位:分)
*/
private long rpayMoney;
/**
* 实际支付金额
*/
private long payMoney;
/**
* 条目交易类型 枚举 2 Y 详见4.4
*/
private EnTradeTypeEnum enTradeType;
/**
* 交易时间 字符 20 Y yyyy-MM-dd HH:mm:ss
*/
private Date payTime;
/**
* 交易状态 字符 2 Y 见4.5
*/
private WkTradeStatusEnum status;
/**
* 交易信息反馈
*/
private String message;
public String getFlowNo() {
return flowNo;
}
public void setFlowNo(String flowNo) {
this.flowNo = flowNo;
}
public String getTradeNo() {
return tradeNo;
}
public void setTradeNo(String tradeNo) {
this.tradeNo = tradeNo;
}
public String getTradeTypeNo() {
return tradeTypeNo;
}
public void setTradeTypeNo(String tradeTypeNo) {
this.tradeTypeNo = tradeTypeNo;
}
public WkChannelNoEnum getTradeChannel() {
return tradeChannel;
}
public void setTradeChannel(WkChannelNoEnum tradeChannel) {
this.tradeChannel = tradeChannel;
}
public String getEntryNo() {
return entryNo;
}
public void setEntryNo(String entryNo) {
this.entryNo = entryNo;
}
public long getRpayMoney() {
return rpayMoney;
}
public void setRpayMoney(long rpayMoney) {
this.rpayMoney = rpayMoney;
}
public long getPayMoney() {
return payMoney;
}
public void setPayMoney(long payMoney) {
this.payMoney = payMoney;
}
public EnTradeTypeEnum getEnTradeType() {
return enTradeType;
}
public void setEnTradeType(EnTradeTypeEnum enTradeType) {
this.enTradeType = enTradeType;
}
public Date getPayTime() {
return payTime;
}
public void setPayTime(Date payTime) {
this.payTime = payTime;
}
public WkTradeStatusEnum getStatus() {
return status;
}
public void setStatus(WkTradeStatusEnum status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* 表示平台所在业务类别
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: RequestTypeEnum.java, v 0.1 2019-06-18 14:04 bangis.wangdf Exp $
*/
public enum ComIdEnum implements WkEnum {
/**
ufc0000 支付平台
000003 小微信贷系统
**/
支付平台("ufc0000", "支付平台"),
小微信贷系统("000003", "小微信贷系统"),
资产转让("000004", "资产转让"),
;
private static final Map<String, ComIdEnum>
codeMap = new HashMap<String, ComIdEnum>();
static {
for (ComIdEnum item : ComIdEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private ComIdEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static ComIdEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public ComIdEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yangcheng
* @version EnTradeTypeEnum.java, v0.12019-06-1817:03 yangchengExp$
*/
public enum EnTradeTypeEnum implements WkEnum {
/**
01 放款
02 扣款
03 充值
04 提现
05 挂账充值
06 挂账提现
**/
放款("01", "放款"),
扣款("02", "扣款"),
充值("03", "充值"),
提现("04", "提现"),
挂账充值("05", "挂账充值"),
挂账提现("06", "挂账提现"),
;
private static final Map<String, EnTradeTypeEnum>
codeMap = new HashMap<String, EnTradeTypeEnum>();
static {
for (EnTradeTypeEnum item : EnTradeTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private EnTradeTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static EnTradeTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public EnTradeTypeEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yangcheng
* @version LocalOrChannelEnum.java, v0.12019-06-1815:56 yangchengExp$
*/
public enum LocalOrChannelEnum implements WkEnum {
/**
0 本地
1 渠道余额
**/
本地("0", "本地"),
渠道余额("1", "渠道余额"),
;
private static final Map<String, LocalOrChannelEnum>
codeMap = new HashMap<String, LocalOrChannelEnum>();
static {
for (LocalOrChannelEnum item : LocalOrChannelEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private LocalOrChannelEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static LocalOrChannelEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public LocalOrChannelEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author yangcheng
* @version PlatResultCodeEnum.java, v0.12019-06-1814:48 yangchengExp$
*/
public enum PlatResultCodeEnum implements WkEnum {
/**
* 10000 成功
* 90000 支付平台异常
**/
成功("10000", "成功"),
支付平台异常("90000", "支付平台异常"),
服务异常("99999", "服务异常"),
异常("9", "异常"),
未知("xxxx", "未知"),
;
private static final Map<String, PlatResultCodeEnum>
codeMap = new HashMap<String, PlatResultCodeEnum>();
static {
for (PlatResultCodeEnum item : PlatResultCodeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private PlatResultCodeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static PlatResultCodeEnum getByCode(String code) {
PlatResultCodeEnum result = codeMap.get(code);
if (result == null) {
if (code.startsWith(异常.code)) {
result = 异常;
} else {
return 未知;
}
}
return result;
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public PlatResultCodeEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: ProjStateEnum.java, v 0.1 2019-06-19 10:56 bangis.wangdf Exp $
*/
public enum ProjStateEnum implements WkEnum {
生效("01", "生效"),
失效("02", "失效"),
;
private static final Map<String, ProjStateEnum>
codeMap = new HashMap<String, ProjStateEnum>();
static {
for (ProjStateEnum item : ProjStateEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private ProjStateEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static ProjStateEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public ProjStateEnum getByWkCode(String code) {
return getByCode(code);
}
}
\ No newline at end of file
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yangcheng
* @version QueryTypeEnum.java, v0.12019-06-1816:31 yangchengExp$
*/
public enum QueryTypeEnum implements WkEnum{
/**
1 按日期区间查询
2 按接口流水号查询
3 按交易交易号查询
4 按交易条目号查询
**/
QT_1("1", "按日期区间查询"),
QT_2("2", "按接口流水号查询"),
QT_3("3", "按交易交易号查询"),
QT_4("4", "按交易条目号查询"),
;
private static final Map<String, QueryTypeEnum>
codeMap = new HashMap<String, QueryTypeEnum>();
static {
for (QueryTypeEnum item : QueryTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private QueryTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static QueryTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public QueryTypeEnum getByWkCode(String code) {
return getByCode(code);
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: RequestTypeEnum.java, v 0.1 2019-06-18 14:04 bangis.wangdf
* Exp $
*/
public enum RequestTypeEnum implements WkEnum {
/**
* 账户信息维护 A100002 1 同步
* 账户状态维护 A100003 1 同步
* 交易代理 P100001 1-50 异步
* 账户余额查询 B100002 1 同步
* 交易结果查询 B100007 1 同步
* 个人要素验证 B100006 1 同步
* A100011 租户信息维护接口 同步
**/
A100002("A100002", "账户信息维护", WkAsynEnum.),
// A100003("A100003", "账户状态维护", WkAsynEnum.是),
A100011("A100011", "租户信息维护", WkAsynEnum.),
P100001("P100001", "交易代理", WkAsynEnum.),
B100002("B100002", "账户余额查询", WkAsynEnum.),
B100007("B100007", "交易结果查询", WkAsynEnum.),
;
private static final Map<String, RequestTypeEnum>
codeMap = new HashMap<String, RequestTypeEnum>();
static {
for (RequestTypeEnum item : RequestTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private WkAsynEnum asyn;
private String code;
private String desc;
private RequestTypeEnum(String code, String desc, WkAsynEnum asyn) {
this.code = code;
this.desc = desc;
this.asyn = asyn;
}
public static RequestTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
public WkAsynEnum getAsyn() {
return asyn;
}
@Override
public RequestTypeEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yangcheng
* @version SettleTypeEnum.java, v0.12019-06-1815:33 yangchengExp$
*/
public enum SettleTypeEnum implements WkEnum {
/**
01 实时结算
02 定时自动结算
**/
实时结算("01", "实时结算"),
定时自动结算("02", "定时自动结算"),
;
private static final Map<String, SettleTypeEnum>
codeMap = new HashMap<String, SettleTypeEnum>();
static {
for (SettleTypeEnum item : SettleTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private SettleTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static SettleTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public SettleTypeEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: TradeQueryTypeEnum.java, v 0.1 2019-06-21 21:25 bangis
* .wangdf Exp $
*/
public enum TradeQueryTypeEnum implements WkEnum {
/**
* 1 按日期区间查询
* 2 按接口流水号查询
* 3 按交易交易号查询
* 4 按交易条目号查询
**/
日期("1", "日期"),
流水号("2", "流水号"),
交易号("3", "交易号"),
条目号("4", "条目号"),
;
private static final Map<String, TradeQueryTypeEnum>
codeMap = new HashMap<String, TradeQueryTypeEnum>();
static {
for (TradeQueryTypeEnum item : TradeQueryTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private TradeQueryTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static TradeQueryTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public TradeQueryTypeEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: TradeTypeEnum.java, v 0.1 2019-06-20 20:22 bangis.wangdf Exp $
*/
public enum TradeTypeEnum implements WkEnum {
/**
* 001 放
* 002 扣款
**/
放款("001", "放款"),
扣款("002", "扣款"),
;
private static final Map<String, TradeTypeEnum>
codeMap = new HashMap<String, TradeTypeEnum>();
static {
for (TradeTypeEnum item : TradeTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private TradeTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static TradeTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public TradeTypeEnum getByWkCode(String code) {
return getByCode(code);
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: WkAccountTypeEnum.java, v 0.1 2019-06-20 21:01 bangis.wangdf
* Exp $
*/
public enum WkAccountTypeEnum implements WkEnum {
/**
* 0 支付平台账号
* 1 个人借记卡
* 2 企业账户
* 3 个人信用卡
**/
支付平台账号("0", "支付平台账号"),
个人借记卡("1", "个人借记卡"),
企业账户("2", "企业账户"),
个人信用卡("3", "个人信用卡"),
;
private static final Map<String, WkAccountTypeEnum>
codeMap = new HashMap();
static {
for (WkAccountTypeEnum item : WkAccountTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
WkAccountTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkAccountTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public WkAccountTypeEnum getByWkCode(String code) {
return getByCode(code);
}
/**
* 枚举编码
*
* @return
*/
@Override
public String getCode() {
return code;
}
/**
* 枚举描述
*
* @return
*/
@Override
public String getDesc() {
return desc;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* 账户类型
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: WkAcctTypeEnum.java, v 0.1 2019-06-19 19:10 bangis.wangdf Exp $
*/
public enum WkAcctKindEnum implements WkEnum {
/**
* 01 为对公,02为对私
**/
对公("01", "对公"),
对私("02", "对私"),
;
private static final Map<String, WkAcctKindEnum>
codeMap = new HashMap();
static {
for (WkAcctKindEnum item : WkAcctKindEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
WkAcctKindEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkAcctKindEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public WkAcctKindEnum getByWkCode(String code) {
return getByCode(code);
}
/**
* 枚举编码
*
* @return
*/
@Override
public String getCode() {
return code;
}
/**
* 枚举描述
*
* @return
*/
@Override
public String getDesc() {
return desc;
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
*
* @author yangcheng
* @version WkTradeStatusEnum.java, v0.12019-06-1815:42 yangchengExp$
*/
public enum WkAcctStatusEnum implements WkEnum {
/**
1 成功
2 失败
**/
成功("1", "成功"),
失败("2", "失败"),
;
private static final Map<String, WkAcctStatusEnum>
codeMap = new HashMap<String, WkAcctStatusEnum>();
static {
for (WkAcctStatusEnum item : WkAcctStatusEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
private WkAcctStatusEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkAcctStatusEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public WkAcctStatusEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* 账户类型
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: WkAcctTypeEnum.java, v 0.1 2019-06-19 19:10 bangis.wangdf Exp $
*/
public enum WkAcctTypeEnum implements WkEnum {
/**
* 1-放款账户,2-扣款账户,3-商户账户,4-费用账户,5-溢缴款账户
**/
放款账户("1", "放款账户"),
扣款账户("2", "扣款账户"),
商户账户("3", "商户账户"),
费用账户("4", "费用账户"),
溢缴款账户("5", "溢缴款账户"),
;
private static final Map<String, WkAcctTypeEnum>
codeMap = new HashMap();
static {
for (WkAcctTypeEnum item : WkAcctTypeEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
WkAcctTypeEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkAcctTypeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public WkAcctTypeEnum getByWkCode(String code) {
return getByCode(code);
}
/**
* 枚举编码
*
* @return
*/
@Override
public String getCode() {
return code;
}
/**
* 枚举描述
*
* @return
*/
@Override
public String getDesc() {
return desc;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: WkAsynEnum.java, v 0.1 2019-06-18 14:19 bangis.wangdf Exp $
*/
public enum WkAsynEnum implements WkEnum {
/**
* ufc0000 支付平台
* 000003 小微信贷系统
**/
("0", "否"),
("1", "是"),
;
private static final Map<String, WkAsynEnum>
codeMap = new HashMap<String, WkAsynEnum>();
static {
for (WkAsynEnum item : WkAsynEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
WkAsynEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkAsynEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public WkAsynEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.general.system.common.util.VarChecker;
import java.util.HashMap;
import java.util.Map;
/**
* @author yangcheng
* @version WkChannelNoEnum.java, v0.12019-06-1815:54 yangchengExp$
*/
public enum WkChannelNoEnum implements WkEnum {
BC_002("002", "工商银行"),
BC_003("003", "农业银行"),
BC_004("004", "中国银行"),
BC_005("005", "建设银行"),
BC_006("006", "交通银行"),
BC_007("007", "招商银行"),
BC_008("008", "中信银行"),
BC_009("009", "浦发银行"),
BC_010("010", "深圳发展银行"),
BC_011("011", "兴业银行"),
BC_012("012", "光大银行"),
BC_014("014", "民生银行"),
BC_015("015", "邮政储蓄"),
BC_016("016", "北京银行"),
BC_017("017", "华夏银行"),
BC_018("018", "上海银行"),
BC_019("019", "广发银行"),
BC_020("020", "平安银行"),
BC_021("021", "宁波银行"),
BC_022("022", "上海农商银行"),
BC_023("023", "北京农商"),
BC_024("024", "青岛银行"),
BC_025("025", "徽商银行"),
BC_026("026", "浙商银行"),
BC_027("027", "东莞银行"),
BC_028("028", "杭州银行"),
BC_029("029", "南京银行"),
BC_030("030", "临商银行"),
BC_031("031", "温州银行"),
BC_032("032", "汉口银行"),
BC_033("033", "江苏银行"),
BC_034("034", "渤海银行"),
BC_035("035", "张家港农商"),
BC_036("036", "深圳农商行"),
BC_037("037", "洛阳银行"),
BC_038("038", "乌鲁木齐商行"),
BC_039("039", "烟台银行"),
BC_040("040", "齐商银行"),
BC_041("041", "浙江民泰商业银行"),
BC_042("042", "大连银行"),
BC_043("043", "哈尔滨银行"),
BC_044("044", "重庆银行"),
BC_045("045", "浙江稠州商业银行"),
BC_046("046", "东莞农商行"),
BC_047("047", "天津银行"),
BC_048("048", "河北银行"),
BC_049("049", "嘉兴银行"),
BC_050("050", "广州银行"),
BC_051("051", "常熟农商行"),
BC_052("052", "顺德农商行"),
BC_053("053", "重庆农商行"),
BC_054("054", "吴江农商行"),
BC_055("055", "西安银行"),
BC_056("056", "长沙银行"),
BC_057("057", "江南农商行"),
BC_058("058", "金华银行"),
BC_059("059", "包商银行"),
BC_060("060", "江阴农商行"),
BC_061("061", "昆山农商行"),
BC_062("062", "郑州银行"),
BC_063("063", "厦门银行"),
BC_064("064", "广州农商行"),
BC_065("065", "华润银行"),
BC_066("066", "华兴银行"),
BC_801("801", "城市商业银行"),
BC_802("802", "农村商业银行"),
BC_803("803", "城市信用社"),
BC_804("804", "农村信用社"),
BC_805("805", "农村合作银行"),
BC_CL0004("CL0004", "快钱"),
BC_CL0001("CL0001", "中金"),
BC_CL0008("CL0008", "兴业银行(银企直通车)"),
BC_CL0005("CL0005", "宝付"),
BC_CL0006("CL0006", "上银联"),
BC_CL0002("CL0002", "广银联"),
BC_CL0007("CL0007", "北京银联"),
BC_CL0009("CL0009", "平安银行(银企直通车)"),
BC_YQ0001("YQ0001", "招商银企"),
;
private static final Map<String, WkChannelNoEnum>
codeMap = new HashMap<String, WkChannelNoEnum>();
static {
for (WkChannelNoEnum item : WkChannelNoEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
WkChannelNoEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkChannelNoEnum getByCode(String code) {
return codeMap.get(code);
}
public static WkChannelNoEnum getPlatChannelNo(String code) {
WkChannelNoEnum noEnum = getByCode(code);
VarChecker.checkNotNull(noEnum,"找不到对应的五矿渠道[{0}]",code);
switch (noEnum) {
case BC_007:
return BC_YQ0001;
case BC_YQ0001:
return noEnum;
default:
throw new AbssqrBizException("未配置对应虚拟账户");
}
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public WkChannelNoEnum getByWkCode(String code) {
return getByCode(code);
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import com.general.system.common.model.IEnum;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.enums: WkEnum.java, v 0.1 2019-06-19 13:39 bangis.wangdf Exp $
*/
public interface WkEnum extends IEnum {
<T extends WkEnum>T getByWkCode(String code) ;
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
/**
* @author yangcheng
* @version PlatResultCodeEnum.java, v0.12019-06-1814:48 yangchengExp$
*/
public enum WkResultCodeEnum implements WkEnum {
/**
* 01-成功 02-失败 03-异常
**/
成功("01", "1", "成功"),
失败("02", "2", "失败"),
异常("03", "3", "异常"),
;
private static final Map<String, WkResultCodeEnum>
codeMap = new HashMap<String, WkResultCodeEnum>();
static {
for (WkResultCodeEnum item : WkResultCodeEnum.values()) {
codeMap.put(item.getCode(), item);
codeMap.put(item.getExtCode(), item);
}
}
private String code;
private String extCode;
private String desc;
WkResultCodeEnum(String code, String extCode, String desc) {
this.code = code;
this.extCode = extCode;
this.desc = desc;
}
public static WkResultCodeEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
public String getExtCode() {
return extCode;
}
@Override
public String getDesc() {
return desc;
}
@Override
public WkResultCodeEnum getByWkCode(String code) {
return getByCode(code);
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.common.integration.wk.enums;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
/**
* @author yangcheng
* @version WkTradeStatusEnum.java, v0.12019-06-1815:42 yangchengExp$
*/
public enum WkTradeStatusEnum implements WkEnum {
/**
* 00000 未使用(仅返回链路状态时使用)
* 1xxxx 成功
* 2xxxx 处理中
* 31xxx 失败-客户原因
* 32xxx 失败-渠道原因
* 33xxx 失败-支付系统原因
* 39xxx 失败-未知失败原因
* 9xxxx 支付平台异常
**/
成功("1", "成功"),
处理中("2", "处理中"),
失败_客户原因("31", "失败_客户原因"),
失败_渠道原因("32", "失败_渠道原因"),
失败_支付系统原因("33", "失败_支付系统原因"),
失败_未知失败原因("39", "失败_未知失败原因"),
支付平台异常("9", "支付平台异常"),
;
private static final Map<String, WkTradeStatusEnum>
codeMap = new HashMap<String, WkTradeStatusEnum>();
static {
for (WkTradeStatusEnum item : WkTradeStatusEnum.values()) {
codeMap.put(item.getCode(), item);
}
}
private String code;
private String desc;
WkTradeStatusEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static WkTradeStatusEnum getByCode(String code) {
return codeMap.get(code);
}
@Override
public String getCode() {
return code;
}
@Override
public String getDesc() {
return desc;
}
@Override
public WkTradeStatusEnum getByWkCode(String code) {
for (WkTradeStatusEnum item : WkTradeStatusEnum.values()) {
if (StringUtils.startsWith(code, item.code)) {
return item;
}
}
return getByCode(code);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.impl;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;
import com.abssqr.plat.common.integration.utils.RestTemplateClient;
import com.abssqr.plat.common.integration.wk.WkPayIntegration;
import com.abssqr.plat.common.integration.wk.domain.Request;
import com.abssqr.plat.common.integration.wk.domain.Result;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.domain.WkHeader;
import com.abssqr.plat.common.integration.wk.domain.config.WkPayConfig;
import com.abssqr.plat.common.integration.wk.domain.opr.OprHeader;
import com.abssqr.plat.common.integration.wk.domain.opr.OprRstHeader;
import com.abssqr.plat.common.integration.wk.domain.opr.request.Project;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.AccountList;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TradeList;
import com.abssqr.plat.common.integration.wk.domain.opr.response.AccountListResult;
import com.abssqr.plat.common.integration.wk.domain.opr.response.ProjectResult;
import com.abssqr.plat.common.integration.wk.domain.qry.QryHeader;
import com.abssqr.plat.common.integration.wk.domain.qry.QryRstHeader;
import com.abssqr.plat.common.integration.wk.domain.qry.request.AccountBalanceParam;
import com.abssqr.plat.common.integration.wk.domain.qry.request.trade.TradeItem;
import com.abssqr.plat.common.integration.wk.domain.qry.request.trade.TradeQuery;
import com.abssqr.plat.common.integration.wk.domain.qry.response.BalanceResult;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.ComIdEnum;
import com.abssqr.plat.common.integration.wk.enums.LocalOrChannelEnum;
import com.abssqr.plat.common.integration.wk.enums.ProjStateEnum;
import com.abssqr.plat.common.integration.wk.enums.RequestTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.TradeQueryTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.utils.XMLUtils;
import com.abssqr.plat.common.util.loggers.CommonLoggers;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.SystemDateUtil;
import com.general.system.common.util.VarChecker;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
/**
* 五矿支付接口
*
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.impl: WkPayIntegrationImpl.java, v 0.1 2019-06-19 11:15 bangis
* .wangdf Exp $
*/
@Repository
public class WkPayIntegrationImpl implements WkPayIntegration {
private final static Logger LOGGER = CommonLoggers.WK_INTEGRATION;
@Autowired
private WkPayConfig wkPayConfig;
@Autowired
private RestTemplateClient restTemplateClient;
private static String hostIp;
private static String requestStart =
"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\""
+ " xmlns:ws=\"http://ws.inf.creditapp.app/\"><soapenv:Header/><soapenv:Body><ws:doAction><!--Optional"
+ ":--><arg0>";
private static String requestBody = "</arg0><!--Optional:--><arg1><![CDATA[";
private static String requestEnd = "]]></arg1></ws:doAction></soapenv:Body></soapenv:Envelope>";
static {
try {
InetAddress addr = InetAddress.getLocalHost();
hostIp = addr.getHostAddress();
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}
/**
* 租户签约与维护
*
* @param seqNo
* @return
*/
@Override
public Result<OprRstHeader, ProjectResult> project(String seqNo, String projNo, String projName) {
Request<OprHeader, Project> request = new Request<>();
OprHeader header = new OprHeader();
buildHeader(header, seqNo, RequestTypeEnum.A100011);
request.setHeader(header);
Project project = new Project();
project.setProjState(ProjStateEnum.生效);
project.setProjName(projName);
project.setProjNo(projNo);
request.setBody(project);
header.setTradeCount(1);
return doPost(request, new Result(OprRstHeader.class,
ProjectResult.class));
}
/**
* 账户信息维护
*
* @param seqNo
* @param accountList
* @return
*/
@Override
public Result<OprRstHeader, AccountListResult> account(String seqNo, List<WkAccount> accountList) {
VarChecker.checkNotEmpty(accountList);
// 组装请求 header
OprHeader header = new OprHeader();
buildHeader(header, seqNo, RequestTypeEnum.A100002);
header.setTradeCount(accountList.size());
// 组装请求 body
AccountList body = new AccountList();
body.setAccountList(accountList);
// 组装参数
Request<OprHeader, AccountList> request = new Request<>();
request.setHeader(header);
request.setBody(body);
return doPost(request, new Result(OprRstHeader.class,
AccountListResult.class));
}
/**
* 账户余额查询 B100002
* 最多50条
*
* @param seqNo
* @param no
* @return
*/
@Override
public Result<QryRstHeader, BalanceResult> balance(String seqNo, String no, WkChannelNoEnum channelNo) {
VarChecker.checkNotEmpty(no);
Request<QryHeader, AccountBalanceParam> request = new Request();
QryHeader header = new QryHeader();
header.setPageNo(1);
header.setPageSize(100);
buildHeader(header, seqNo, RequestTypeEnum.B100002);
request.setHeader(header);
AccountBalanceParam body = new AccountBalanceParam();
body.setNo(no);
body.setChannelNo(channelNo);
body.setLocalOrChannel(LocalOrChannelEnum.getByCode(wkPayConfig.getBalanceType()));
request.setBody(body);
return doPost(request, new Result(QryRstHeader.class,
BalanceResult.class));
}
/**
* 交易接口调用
*
* @param seqNo
* @param tradeList
* @return
*/
@Override
public Result<OprRstHeader, WkBody> trade(String seqNo, TradeList tradeList) {
VarChecker.checkNotNull(tradeList);
Request<OprHeader, TradeList> request = new Request<>();
OprHeader header = new OprHeader();
buildHeader(header, seqNo, RequestTypeEnum.P100001);
header.setTradeCount(tradeList.getTradeList().size());
header.setReturnUrl(wkPayConfig.getTradeCallBackUrl());
request.setHeader(header);
request.setBody(tradeList);
return doPost(request, new Result(OprRstHeader.class,
AccountListResult.class));
}
/**
* 交易结果查询
*
* @param seqNo
* @param entryNos
* @return
*/
@Override
public Result<QryRstHeader, TradeResult> tradeRstQry(String seqNo, List<String> entryNos) {
VarChecker.checkNotEmpty(entryNos);
Request<QryHeader, TradeQuery> request = new Request<>();
QryHeader header = new QryHeader();
buildHeader(header, seqNo, RequestTypeEnum.B100007);
header.setPageNo(1);
header.setPageSize(entryNos.size());
request.setHeader(header);
TradeQuery body = new TradeQuery();
body.setQueryType(TradeQueryTypeEnum.条目号);
List<TradeItem> list = Lists.newArrayList();
entryNos.forEach(entryNo -> {
TradeItem item = new TradeItem();
item.setNo(entryNo);
list.add(item);
});
body.setQueryList(list);
request.setBody(body);
return doPost(request, new Result(QryRstHeader.class, TradeResult.class));
}
private <T extends Result> T doPost(Request request, T result) {
String requestXml = genFullXml(request);
LogUtil.info(LOGGER, "**********[request.header.type]-{0}", request.getHeader().getRequestType());
LogUtil.info(LOGGER, "**********[request.body]-{0}", requestXml);
String response = "";
try {
response = restTemplateClient.postXml(wkPayConfig.getHost(), requestXml);
} finally {
VarChecker.checkNotEmpty(response,"response is null");
LogUtil.info(LOGGER, "**********[response]-{0}", response);
}
return toModel(response, result);
}
private <T extends Result> T toModel(String resultXml, T result) {
int start = StringUtils.indexOf(resultXml, "<return>");
int end = StringUtils.indexOf(resultXml, "</return>");
String substring = StringUtils.substring(resultXml, start + 8, end);
String aResult = StringUtils.replaceAll(substring, "&lt;", "<");
aResult = StringUtils.replaceAll(aResult, "&gt;", ">");
aResult = StringUtils.replaceAll(aResult, "&quot;", "\"");
LogUtil.info(LOGGER, "**********[request.body]-result-{0}", aResult);
XMLUtils.xmlToModel(aResult, result, true);
return result;
}
private void buildHeader(WkHeader wkHeader, String seqNo, RequestTypeEnum requestType) {
wkHeader.setComId(ComIdEnum.资产转让);
wkHeader.setAsyn(requestType.getAsyn());
wkHeader.setRequestType(requestType);
wkHeader.setSendTime(SystemDateUtil.getSystemDate());
wkHeader.setComIP(hostIp);
wkHeader.setUUID(seqNo);
}
private String genFullXml(Request request) {
StringBuilder stringBuilder = new StringBuilder(requestStart);
stringBuilder.append(request.getHeader().getRequestType().getCode());
stringBuilder.append(requestBody);
stringBuilder.append(XMLUtils.modelToXml(request, true));
stringBuilder.append(requestEnd);
return stringBuilder.toString();
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.utils;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.integration.wk.enums.ComIdEnum;
import com.abssqr.plat.common.integration.wk.enums.EnTradeTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.TradeTypeEnum;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.general.system.common.util.StringFormatUtil;
import static com.general.system.common.util.MessageUtil.formatMsg;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.utils: WkSequenceUtil.java, v 0.1 2019-06-21 22:33 bangis.wangdf Exp $
*/
public class WkSequenceUtil {
public static class Account {
/**
* 生成五矿需要的虚拟账户号
*
* @param tradeType
* @param planNo
* @return
*/
public static String genAccountNo(TradeTypeEnum tradeType, String planNo, AccountAttributeEnum actAttr) {
return formatMsg("{0}_{1}_{2}_{3}",
//前缀
ComIdEnum.资产转让.getCode(), tradeType.getCode(), planNo,actAttr.getCode());
}
/**
* 生成五矿需要的虚拟账户号
*
* @param tradeType
* @param planName
* @return
*/
public static String genAccountName(TradeTypeEnum tradeType, String planName, AccountAttributeEnum actAttr) {
return formatMsg("{0}_{1}_{2}-{3}-{4}",
//前缀
ComIdEnum.资产转让.getCode(), tradeType.getCode(), planName, tradeType.getDesc(),actAttr.getDesc());
}
/**
* 生成五矿需要的虚拟账户号
*
* @param planNo
* @return
*/
public static String genCustNo(String planNo) {
return formatMsg("{0}_{1}",
//前缀
ComIdEnum.资产转让.getCode(), planNo);
}
/**
* 生成五矿需要的虚拟账户号
*
* @param planName
* @return
*/
public static String genCustName(String planName) {
return formatMsg("{0}_{1}",
//前缀
ComIdEnum.资产转让.getCode(), planName);
}
}
public static class Trade {
/**
* 交易号
*
* @return
*/
public static String genTradeNo() {
return formatMsg("{0}_{1}", ComIdEnum.资产转让.getCode(), SequenceUtil.genWkSeqNo("td"));
}
/**
* 条目号
*
* @return
*/
public static String genEntryNo() {
return formatMsg("{0}_{1}", ComIdEnum.资产转让.getCode(), SequenceUtil.genWkSeqNo("en"));
}
/**
* 条目类型编号
*
* @return
*/
public static String genEntryTypeNo(EnTradeTypeEnum enTradeType, int idx) {
return formatMsg("{0}{1}", enTradeType.getCode(),
StringFormatUtil.formatTransSeqByNumber(Long.valueOf(idx)));
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.utils;
import java.lang.reflect.Field;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.XmlUtil;
import com.abssqr.plat.common.integration.wk.domain.Request;
import com.abssqr.plat.common.integration.wk.domain.Result;
import com.abssqr.plat.common.integration.wk.utils.converter.ElementConverters;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.common.model.wk.utils: XMLUtils.java, v 0.1 2019-06-18 16:23 bangis.wangdf Exp $
*/
public class XMLUtils {
public static <T extends Result> T xmlToModel(String xml, T model, boolean uncapFirst) {
Document document = XmlUtil.parseXml(xml);
Field[] fields = ReflectUtil.getFields(model.getClass());
Element rootElement = XmlUtil.getRootElement(document);
for (Field field : fields) {
String elemntName = ElementConverters.fileName(uncapFirst, field.getName());
Element element = XmlUtil.getElement(rootElement, elemntName);
if (field.getName().equals("header")) {
ElementConverters.elementFillModel(element, model, field, model.getHeaderClazz(), uncapFirst);
} else if (field.getName().equals("body")) {
ElementConverters.elementFillModel(element, model, field, model.getBodyClazz(), uncapFirst);
}
}
return model;
}
public static String modelToXml(Request wkPackage, boolean uncapFirst) {
Field[] fields = ReflectUtil.getFields(wkPackage.getClass());
String rootStr = ElementConverters.elementName(wkPackage, uncapFirst);
Document root = XmlUtil.createXml(rootStr);
for (Field field : fields) {
String elemntName = ElementConverters.elementName(field, uncapFirst);
Element element = ElementConverters.appendElement(root.getDocumentElement(), elemntName);
ElementConverters.appendElement(element, ReflectUtil.getFieldValue(wkPackage, field), uncapFirst);
}
return XmlUtil.toStr(root, false);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.common.integration.wk.utils.converter;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.XmlUtil;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.domain.WkObject;
import com.abssqr.plat.common.integration.wk.enums.WkEnum;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.exception.AbssqrInvalidParamException;
import com.general.system.common.model.IEnum;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.IEnumUtil;
import com.general.system.common.util.LogUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
/**
* XML节点转换
* @author bangis.wangdf
* @version com.abssqr.plat.common.integration.wk.utils.converter: ElementConverters.java, v 0.1 2019-06-18 17:26 bangis
* .wangdf Exp $
*/
public class ElementConverters {
/**
* Dispatcher调度日志
*/
public final static Logger LOGGER = LoggerFactory.getLogger(ElementConverters.class);
public static void appendElement(Element element, Object model, boolean uncapFirst) {
if (model == null) {
element.setTextContent(null);
return;
}
if (model instanceof Integer) {
element.setTextContent(model.toString());
} else if (model instanceof Long) {
element.setTextContent(model.toString());
} else if (model instanceof Double) {
element.setTextContent(model.toString());
} else if (model instanceof String) {
element.setTextContent(model.toString());
} else if (model instanceof IEnum) {
element.setTextContent(String.valueOf(((IEnum)model).getCode()));
} else if (model instanceof Date) {
element.setTextContent(DateTimeUtil.formatYMDHMSSLong((Date)model));
} else if (model instanceof List) {
for (Object obj : ((List)model)) {
if (obj instanceof WkObject) {
String elemntName = elementName((WkObject)obj, uncapFirst);
Element childElement = appendElement(element, elemntName);
appendElement(childElement, obj, uncapFirst);
} else {
//不支持的类型
LogUtil.error(LOGGER,"转五矿支付XML时仅支持WkObject");
throw new AbssqrInvalidParamException("转五矿支付XML时仅支持WkObject");
}
}
} else if (model instanceof WkBody) {
String elemntName = elementAnnotationName((WkObject)model, uncapFirst);
Element childElement = element;
if (StringUtils.isNotBlank(elemntName)) {
childElement = appendElement(element, elemntName);
}
Field[] fields = ReflectUtil.getFields(model.getClass());
if (fields != null) {
for (Field field : fields) {
String childElemntName = elementName(field, uncapFirst);
Element _childElement = appendElement(childElement, childElemntName);
Object fieldValue = ReflectUtil.getFieldValue(model, field);
appendElement(_childElement, fieldValue, uncapFirst);
}
}
} else if (model instanceof WkObject) {
Field[] fields = ReflectUtil.getFields(model.getClass());
if (fields != null) {
for (Field field : fields) {
String elemntName = elementName(field, uncapFirst);
Element childElement = appendElement(element, elemntName);
Object fieldValue = ReflectUtil.getFieldValue(model, field);
appendElement(childElement, fieldValue, uncapFirst);
}
}
} else {
//不支持的类型
LogUtil.error(LOGGER,"转五矿支付XML时不支持的类型:"+model.getClass());
throw new AbssqrInvalidParamException("转五矿支付XML时不支持的类型:"+model.getClass());
}
}
public static String fileName(boolean uncapFirst, String name) {
return uncapFirst ? StrUtil.upperFirst(name) : StrUtil.lowerFirst(
name);
}
public static Element appendElement(Element parent, String tagName) {
Element child = parent.getOwnerDocument().createElement(tagName);
parent.appendChild(child);
return child;
}
public static <T> void elementFillModel(Element element, T model, Field field, Class fieldClazz,
boolean uncapFirst) {
if (element == null) {
return;
}
Class<?> typeClass = field.getType();
if (String.class.isAssignableFrom(typeClass)) {
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
} else if (Integer.class.isAssignableFrom(typeClass)) {
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
} else if (Long.class.isAssignableFrom(typeClass)) {
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
} else if (Double.class.isAssignableFrom(typeClass)) {
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
} else if (IEnum.class.isAssignableFrom(typeClass)) {
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
} else if (Date.class.isAssignableFrom(typeClass)) {
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
} else if (List.class.isAssignableFrom(typeClass)) {
List list = Lists.newArrayList();
Class aClass = listFClass(field);
if (WkObject.class.isAssignableFrom(aClass)) {
try {
Object instance = aClass.newInstance();
String childFileName = elementName((WkObject)instance, uncapFirst);
Field[] fields = ReflectUtil.getFields(aClass);
List<Element> elements = XmlUtil.getElements(element, childFileName);
if (CollectionUtils.isNotEmpty(elements)) {
for (Element _element : elements) {
instance = aClass.newInstance();
for (Field childField : fields) {
String _childFileName = fileName(uncapFirst, childField.getName());
Element childElement = XmlUtil.getElement(_element, _childFileName);
elementFillModel(childElement, instance, childField, childField.getType(), uncapFirst);
}
list.add(instance);
}
}
} catch (Throwable e) {
LogUtil.error(LOGGER,"五矿XML转内部模型失败");
throw new AbssqrBizException("五矿XML转内部模型失败",e);
}
} else {
LogUtil.error(LOGGER,"五矿XML转内部模型时不支持的类型:"+model.getClass());
throw new AbssqrInvalidParamException("五矿XML转内部模型时不支持的类型:"+model.getClass());
}
ReflectUtil.setFieldValue(model, field, list);
} else if (WkBody.class.isAssignableFrom(typeClass)) {
try {
Object childObj = fieldClazz.newInstance();
Element _element = element;
String elementName = elementAnnotationName((WkObject)childObj, uncapFirst);
if (StringUtils.isNotBlank(elementName)) {
_element = XmlUtil.getElement(element, elementName);
}
Field[] fields = ReflectUtil.getFields(childObj.getClass());
for (Field childField : fields) {
String childFileName = fileName(uncapFirst, childField.getName());
Element childElement = XmlUtil.getElement(_element, childFileName);
elementFillModel(childElement, childObj, childField, childField.getType(), uncapFirst);
}
ReflectUtil.setFieldValue(model, field, childObj);
} catch (Throwable e) {
throw new RuntimeException(e);
}
} else if (WkObject.class.isAssignableFrom(typeClass)) {
try {
Object childObj = fieldClazz.newInstance();
Field[] fields = ReflectUtil.getFields(childObj.getClass());
for (Field childField : fields) {
String childFileName = fileName(uncapFirst, childField.getName());
Element childElement = XmlUtil.getElement(element, childFileName);
elementFillModel(childElement, childObj, childField, childField.getType(), uncapFirst);
}
ReflectUtil.setFieldValue(model, field, childObj);
} catch (Throwable e) {
throw new RuntimeException(e);
}
}else{
ReflectUtil.setFieldValue(model, field, elementText(element, typeClass));
}
}
private static Map<String, Class> listClassMap = Maps.newHashMap();
private static Class listFClass(Field field) {
String typeName = field.getGenericType().getTypeName();
Class result = listClassMap.get(typeName);
if (result == null) {
String className = StringUtils.substring(typeName, StringUtils.indexOf(typeName, "<") + 1,
StringUtils.indexOf(typeName, ">"));
try {
result = Class.forName(className);
listClassMap.put(typeName, result);
} catch (ClassNotFoundException e) {
}
}
return result;
}
private static Object elementText(Element element, Class clazz) {
String text = element == null ? null : element.getTextContent();
Object result = null;
if (StringUtils.isNotBlank(text)) {
if (String.class.isAssignableFrom(clazz)) {
result = text;
} else if (Integer.class.isAssignableFrom(clazz)) {
result = Integer.valueOf(text);
}else if (int.class.isAssignableFrom(clazz)) {
result = Integer.valueOf(text);
} else if (Long.class.isAssignableFrom(clazz)) {
result = Long.valueOf(text);
}else if (long.class.isAssignableFrom(clazz)) {
String cent = StringUtils.removeEnd(text,".00");
result = Long.valueOf(cent);
} else if (Double.class.isAssignableFrom(clazz)) {
result = Double.valueOf(text);
}else if (double.class.isAssignableFrom(clazz)) {
result = Double.valueOf(text);
} else if (WkEnum.class.isAssignableFrom(clazz)) {
List enumList = IEnumUtil.getEnumList(clazz);
if (CollectionUtils.isNotEmpty(enumList)) {
result = ((WkEnum)enumList.get(0)).getByWkCode(text);
}
} else if (IEnum.class.isAssignableFrom(clazz)) {
result = IEnumUtil.getEnum(clazz, text);
} else if (Date.class.isAssignableFrom(clazz)) {
result = DateTimeUtil.parseInTolerance(text);
} else {
LogUtil.error(LOGGER,"五矿XML转内部模型失败");
throw new AbssqrBizException("五矿XML转内部模型失败");
}
}
return result;
}
public static String elementName(Field field, boolean uncapFirst) {
String elemntName = ElementConverters.fileName(uncapFirst, field.getName());
XmlElement annotation = field.getAnnotation(XmlElement.class);
if (annotation != null) {
elemntName = annotation.name();
}
return elemntName;
}
public static String elementName(WkObject wkObject, boolean uncapFirst) {
String rootStr = elementAnnotationName(wkObject, uncapFirst);
if (StringUtils.isBlank(rootStr)) {
rootStr = uncapFirst ? wkObject.getClass().getSimpleName() : StrUtil.lowerFirst(
wkObject.getClass().getSimpleName());
}
return rootStr;
}
private static String elementAnnotationName(WkObject wkObject, boolean uncapFirst) {
String rootStr = null;
XmlRootElement xmlRootElement = wkObject.getClass().getAnnotation(XmlRootElement.class);
XmlElement xmlElement = wkObject.getClass().getAnnotation(XmlElement.class);
if (xmlElement != null) {
rootStr = xmlElement.name();
} else if (xmlRootElement != null) {
rootStr = xmlRootElement.name();
}
return rootStr;
}
}
......@@ -7,11 +7,7 @@ package com.abssqr.plat.core.service.acct;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.model.repo.acct.AcctRepo;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.general.system.common.util.VarChecker;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
......@@ -33,8 +29,6 @@ public class AcctManager {
@Autowired
private AcctRepo acctRepo;
@Autowired
private WkPayManager wkPayManager;
/**
* 新增or编辑银行账号
......@@ -86,33 +80,13 @@ public class AcctManager {
if (balance) {
accounts.forEach(account -> {
//如果是银行账户则查询映射渠道号,否则查询渠道号
WkChannelNoEnum channelNo=WkChannelNoEnum.getPlatChannelNo(isBank ? account.getMapChannelNo() : account.getChannelNo());
//如果是银行账户则查询映射账户编号,否则查询账户编号
String actNo= isBank ? account.getMapActNo() : account.getActNo();
//查询余额
account.setBankBal(wkPayManager.balance(actNo, channelNo));
});
}
return accounts;
}
/**
* 1 创建平台虚拟户
* 2 调用五矿接口进行开户
*
* @param planNo
*/
public void createPlatAcct(String planNo, String planName,List<Account> accounts){
// 创建账户
for (Account account : accounts) {
if (account.getActAttr().isNeedPlat()) {
WkChannelNoEnum channelNo = WkChannelNoEnum.getPlatChannelNo(account.getChannelNo());
VarChecker.checkNotNull(channelNo, "新增平台虚拟户失败,找不到对应的渠道号");
createPlatAcct(planNo, planName, account.getActAttr(), channelNo);
}
}
}
/**
* 查询虚拟户并添加虚拟号和对应渠道号至对应银行户
......@@ -155,27 +129,5 @@ public class AcctManager {
}
return bankAccounts;
}
/**
* 1 创建平台虚拟户
* 2 调用五矿接口进行开户
*
* @param planNo
*/
private void createPlatAcct(String planNo, String planName, AccountAttributeEnum actAttr,
WkChannelNoEnum channelNo) {
List<Account> accounts = acctRepo.getAcctByPlanNo(planNo, actAttr,
Lists.newArrayList(AccountTypeEnum.PLAT_VIRTUAL));
if (CollectionUtils.isEmpty(accounts)) {
VarChecker.checkNotNull(channelNo);
WkAccount wkAccount = wkPayManager.createAccount(planNo, planName, actAttr);
Account account = new Account();
account.setActType(AccountTypeEnum.PLAT_VIRTUAL);
account.setActNo(wkAccount.getAccountNo());
account.setActName(wkAccount.getAccountName());
account.setChannelNo(channelNo.getByWkCode(channelNo.getCode()).getCode());
account.setActAttr(actAttr);
acctRepo.addOrUpdateAccounts(planNo, Lists.newArrayList(account));
}
}
}
......@@ -4,6 +4,12 @@
*/
package com.abssqr.plat.core.service.plan;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import com.abssqr.plat.common.dal.mysql.auto.paging.PlanListPage;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.enums.CalcTypeEnum;
......@@ -28,7 +34,6 @@ import com.abssqr.plat.common.model.enums.IdTypeEnum;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.acct.AcctRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAcctTitleRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAstPriceRuleRepo;
import com.abssqr.plat.common.model.repo.plan.PlanFeeStructureRepo;
import com.abssqr.plat.common.model.repo.plan.PlanInvestStructureRepo;
......@@ -45,6 +50,7 @@ import com.abssqr.plat.core.service.acct.AcctManager;
import com.abssqr.plat.core.service.change.ApproveCallBack;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.core.service.org.OrgManager;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.model.enums.CommonErrorCodeEnum;
import com.general.system.common.model.exception.BaseCommonException;
......@@ -62,12 +68,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
* 计划核心服务
*
......@@ -100,12 +100,8 @@ public class PlanManager implements ApproveCallBack<PlanBase> {
@Autowired
AstScreenRuleRepo astScreenRuleRepo;
@Autowired
PlanAstManager planAstManager;
@Autowired
PlanAcctTitleRepo planAcctTitleRepo;
@Autowired
PlanAllocRepo planAllocRepo;
@Autowired
AstSyncTaskCtrRepo astSyncTaskCtrRepo;
@Autowired
PlanAstPriceRuleRepo planAstPriceRuleRepo;
......@@ -118,7 +114,7 @@ public class PlanManager implements ApproveCallBack<PlanBase> {
@Autowired
PlanReportRepo planReportRepo;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
OrgAcctDayComponent orgAcctDayComponent;
@Override
public DataChangeBizTypeEnum getChangeType() {
......@@ -398,14 +394,10 @@ public class PlanManager implements ApproveCallBack<PlanBase> {
//初始化计划科目
planAcctTitleManager.initPlanAcctTitles(dbPlan, planModel.getEffectDate(),
planModel.getInvestStructureList(), planModel.getFeeStructureList());
// 投入资本到账 初始化成立发行日上一日空值报表基础数据
planReportRepo.defaultRPT001Init(planModel.getPlanNo(), planModel.getBeginDate());
//创建平台虚拟户
acctManager.createPlatAcct(planModel.getPlanNo(), planModel.getPlanName(), planModel.getAccounts());
//初始化水位
planAstManager.initPlanAst(planModel.getPlanNo(), planModel.getPlanType(), accountDate);
//初始化分配计划
planAllocManager.initOrAppendAlloc(planModel, dbPlan.getStatus(), accountDate);
......@@ -464,71 +456,72 @@ public class PlanManager implements ApproveCallBack<PlanBase> {
}
// 兼容代码删除
// public void initPlanFor20191030() {
// List<PlanBase> spvPlans = planRepo.getPlansByStatus(PlanTypeEnum.SPV, PlanStatusEnum.ONGOING);
//
// if (CollectionUtils.isNotEmpty(spvPlans)) {
// spvPlans.forEach(planBase -> {
// fillPlanInfo(planBase, false);
// LogUtil.info(LOGGER, "补偿放款计划-水位[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// //初始化水位
// planAstManager.initPlanAst(planBase.getPlanNo(), planBase.getPlanType());
// //金融服务费补偿
// LogUtil.info(LOGGER, "补偿放款计划-金融服务费[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// finFeeCompensate(planBase);
//
// //初始化计划科目
// LogUtil.info(LOGGER, "补偿放款计划-初始化计划科目[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// planAcctTitleManager.initPlanAcctTitles(planBase, planBase.getEffectDate(),
// planBase.getInvestStructureList(), planBase.getFeeStructureList());
//
// //初始化分配计划
// LogUtil.info(LOGGER, "补偿放款计划-初始化分配计划[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// planAllocManager.initOrAppendAlloc(planBase, planBase.getStatus());
//
// });
// }
//
// List<PlanBase> plans = planRepo.getPlansByStatus(PlanTypeEnum.PLAN, PlanStatusEnum.ONGOING);
//
// if (CollectionUtils.isNotEmpty(plans)) {
// plans.forEach(planBase -> {
// fillPlanInfo(planBase, false);
// //金融服务费补偿
// LogUtil.info(LOGGER, "补偿受让计划-金融服务费补偿[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// FeeStructure feeStructure = finFeeCompensate(planBase);
// //初始化计划科目
// LogUtil.info(LOGGER, "补偿受让计划-金融服务费科目[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// planAcctTitleManager.initPlanAcctTitles(planBase, planBase.getEffectDate(),
// planBase.getInvestStructureList(), planBase.getFeeStructureList());
//
// //补偿分配方案
// if (feeStructure != null) {
//
// List<PlanAcctTitle> planAcctTitles = planAcctTitleRepo.getByEntityNo(planBase.getPlanNo());
// PlanAcctTitle planAcctTitle = planAcctTitles.stream().filter(
// t -> StringUtils.equals(t.getRefNo(), feeStructure.getFeeNo())).findFirst().get();
// List<PlanAlloc> planAllocs = planAllocManager.queryAllocByEntityNo(planBase.getPlanNo());
// if (CollectionUtils.isNotEmpty(planAllocs)) {
// planAllocs.forEach(planAlloc -> {
// PlanAllocItem allocItem = new PlanAllocItem();
// allocItem.setItemNo(SequenceUtil.genId(IdTypeEnum.ALLOCITM));
// allocItem.setTax(true);
// allocItem.setTitleNo(planAcctTitle.getTitleNo());
// allocItem.setTitleName(planAcctTitle.getTitleName());
// allocItem.setRelNo(feeStructure.getFeeNo());
// allocItem.setLayerOrder(0);
// allocItem.setOrder(0);
// LogUtil.info(LOGGER, "补偿受让计划-分配方案[{0}][{1}][{2}]", planBase.getPlanNo(),
// planBase.getPlanName(), allocItem.getItemNo());
// planAllocRepo.insertPlanAllocItem(allocItem, planBase.getPlanNo(), planAlloc.getAllocNo());
// });
// }
// }
// });
//
// }
// }
// public void initPlanFor20191030() {
// List<PlanBase> spvPlans = planRepo.getPlansByStatus(PlanTypeEnum.SPV, PlanStatusEnum.ONGOING);
//
// if (CollectionUtils.isNotEmpty(spvPlans)) {
// spvPlans.forEach(planBase -> {
// fillPlanInfo(planBase, false);
// LogUtil.info(LOGGER, "补偿放款计划-水位[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// //初始化水位
// planAstManager.initPlanAst(planBase.getPlanNo(), planBase.getPlanType());
// //金融服务费补偿
// LogUtil.info(LOGGER, "补偿放款计划-金融服务费[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// finFeeCompensate(planBase);
//
// //初始化计划科目
// LogUtil.info(LOGGER, "补偿放款计划-初始化计划科目[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// planAcctTitleManager.initPlanAcctTitles(planBase, planBase.getEffectDate(),
// planBase.getInvestStructureList(), planBase.getFeeStructureList());
//
// //初始化分配计划
// LogUtil.info(LOGGER, "补偿放款计划-初始化分配计划[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// planAllocManager.initOrAppendAlloc(planBase, planBase.getStatus());
//
// });
// }
//
// List<PlanBase> plans = planRepo.getPlansByStatus(PlanTypeEnum.PLAN, PlanStatusEnum.ONGOING);
//
// if (CollectionUtils.isNotEmpty(plans)) {
// plans.forEach(planBase -> {
// fillPlanInfo(planBase, false);
// //金融服务费补偿
// LogUtil.info(LOGGER, "补偿受让计划-金融服务费补偿[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// FeeStructure feeStructure = finFeeCompensate(planBase);
// //初始化计划科目
// LogUtil.info(LOGGER, "补偿受让计划-金融服务费科目[{0}][{1}]", planBase.getPlanNo(), planBase.getPlanName());
// planAcctTitleManager.initPlanAcctTitles(planBase, planBase.getEffectDate(),
// planBase.getInvestStructureList(), planBase.getFeeStructureList());
//
// //补偿分配方案
// if (feeStructure != null) {
//
// List<PlanAcctTitle> planAcctTitles = planAcctTitleRepo.getByEntityNo(planBase.getPlanNo());
// PlanAcctTitle planAcctTitle = planAcctTitles.stream().filter(
// t -> StringUtils.equals(t.getRefNo(), feeStructure.getFeeNo())).findFirst().get();
// List<PlanAlloc> planAllocs = planAllocManager.queryAllocByEntityNo(planBase.getPlanNo());
// if (CollectionUtils.isNotEmpty(planAllocs)) {
// planAllocs.forEach(planAlloc -> {
// PlanAllocItem allocItem = new PlanAllocItem();
// allocItem.setItemNo(SequenceUtil.genId(IdTypeEnum.ALLOCITM));
// allocItem.setTax(true);
// allocItem.setTitleNo(planAcctTitle.getTitleNo());
// allocItem.setTitleName(planAcctTitle.getTitleName());
// allocItem.setRelNo(feeStructure.getFeeNo());
// allocItem.setLayerOrder(0);
// allocItem.setOrder(0);
// LogUtil.info(LOGGER, "补偿受让计划-分配方案[{0}][{1}][{2}]", planBase.getPlanNo(),
// planBase.getPlanName(), allocItem.getItemNo());
// planAllocRepo.insertPlanAllocItem(allocItem, planBase.getPlanNo(), planAlloc
// .getAllocNo());
// });
// }
// }
// });
//
// }
// }
private FeeStructure finFeeCompensate(PlanBase planBase) {
FeeStructure result = null;
......
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.service.wk.pay;
import java.util.List;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.general.system.common.model.Money;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 支付管理 - 五矿支付
*
* @author bangis.wangdf
* @version com.abssqr.plat.core.service.wk.pay: WkPayManager.java, v 0.1 2019-06-22 11:40 bangis.wangdf Exp $
*/
@Component
public class WkPayManager implements WkPayService {
@Autowired
AbsConfig absConfig;
@Override
public boolean project() {
return getInstance(absConfig.getEnv()).project();
}
@Override
public WkAccount createAccount(String planNo, String planName, AccountAttributeEnum actAttr) {
return getInstance(absConfig.getEnv()).createAccount(planNo, planName, actAttr);
}
@Override
public Money balance(String accountNo, WkChannelNoEnum channelNo) {
return getInstance(absConfig.getEnv()).balance(accountNo, channelNo);
}
@Override
public String trade(Account sourceAcct, Account targetAcct, Money money,String remark1) {
return getInstance(absConfig.getEnv()).trade(sourceAcct, targetAcct, money,remark1);
}
@Override
public TradeResult tradeRstQry(List<String> entryNos) {
return getInstance(absConfig.getEnv()).tradeRstQry(entryNos);
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.service.wk.pay;
import java.util.List;
import java.util.Map;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil.Trade;
import com.general.system.common.model.Money;
import com.google.common.collect.Maps;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.core.service.wk.pay: WkPayService.java, v 0.1 2019-12-15 14:22 bangis.wangdf Exp $
*/
public interface WkPayService {
Map<String, WkPayService> serviceMap = Maps.newHashMap();
/**
* 租户签约与维护
*
* @return
*/
boolean project();
/**
* 创建账户号
* 重复调用不会改天
*
* @return 返回支付平台虚拟号
*/
WkAccount createAccount(String planNo, String planName, AccountAttributeEnum actAttr);
/**
* 查询账户余额
* 创建完虚拟号后再没有关联实际银行卡时result.getBody()=null
*
* @param accountNo
* @return
*/
Money balance(String accountNo, WkChannelNoEnum channelNo);
/**
* 只有放款逻辑
* 五矿支付接口返回状态只有受理成功与平台异常,
* 平台异常时无法保证资金是否会转让
*
* @param sourceAcct 源账号
* @param targetAcct 目标账号
* @param money
* @param remark1 备注
* @return 条目号
* @see Trade#genTradeNo()
*/
String trade(Account sourceAcct, Account targetAcct, Money money,String remark1);
/**
* 代理交易结果查询
* 只支持4 做查询
*
* @param entryNos
* @return TradeResult 可能为空
*/
TradeResult tradeRstQry(List<String> entryNos);
default String type() {
return "mock";
}
default WkPayService getInstance(String type){
WkPayService wkPayService = serviceMap.get(type);
if(wkPayService==null){
wkPayService = serviceMap.get("mock");
}
return wkPayService;
}
default void register() {
serviceMap.put(type(), this);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.service.wk.pay.impl;
import javax.annotation.PostConstruct;
import com.abssqr.plat.core.service.wk.pay.WkPayService;
/**
*
* @author bangis.wangdf
* @version com.abssqr.plat.core.service.wk.pay.impl: AbsWkPayService.java, v 0.1 2019-12-15 15:29 bangis.wangdf Exp $
*/
public abstract class AbsWkPayService implements WkPayService {
@PostConstruct
public void init() {
register();
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.service.wk.pay.impl;
import java.util.List;
import com.abssqr.plat.common.dal.mysql.auto.dao.LoanDAO;
import com.abssqr.plat.common.dal.mysql.auto.resultmap.LoanPropCntStat;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.plan.PlanAst;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.integration.wk.domain.config.WkPayConfig;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.TradeTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAcctKindEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAcctTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil;
import com.abssqr.plat.common.model.repo.acct.AcctRepo;
import com.abssqr.plat.common.model.repo.ast.LoanRepository;
import com.abssqr.plat.common.model.repo.plan.PlanAstRepository;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.general.system.common.model.Money;
import com.general.system.common.util.VarChecker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.core.service.wk.pay.impl: WkPayMockServiceImpl.java, v 0.1 2019-12-15 14:40 bangis.wangdf
* Exp $
*/
@Service
public class WkPayMockServiceImpl extends AbsWkPayService {
@Autowired
private WkPayConfig wkPayConfig;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanAstRepository planAstRepository;
@Autowired
private AcctRepo acctRepo;
@Autowired
private PlanManager planManager;
@Autowired
private LoanDAO loanDAO;
@Override
public boolean project() {
return true;
}
@Override
public WkAccount createAccount(String planNo, String planName, AccountAttributeEnum actAttr) {
WkAccount account = new WkAccount();
account.setAccountName(WkSequenceUtil.Account.genAccountName(TradeTypeEnum.放款, planName, actAttr));
account.setAccountNo(WkSequenceUtil.Account.genAccountNo(TradeTypeEnum.放款, planNo, actAttr));
account.setAcctKind(WkAcctKindEnum.对公);
account.setAcctType(WkAcctTypeEnum.放款账户);
account.setCustName(WkSequenceUtil.Account.genCustName(planName));
account.setCustNo(WkSequenceUtil.Account.genCustNo(planNo));
// 租户编号
account.setTenantNo(wkPayConfig.getProjNo());
return account;
}
@Override
public Money balance(String accountNo, WkChannelNoEnum channelNo) {
Account account = acctRepo.getAcctsByAccountNo(accountNo);
VarChecker.checkNotNull(account);
PlanAst planAst = planAstRepository.getByPlanNo(account.getPlanNo());
PlanBase planBase = planManager.getPlanFullByNo(account.getPlanNo());
if (planBase.getPlanType() == PlanTypeEnum.SPV) {
//回款户
if (account.getActAttr() == AccountAttributeEnum.RECV) {
//受让池 -- 非初始化查询
if (planAst.getStatus() != TaskStatusEnum.INIT) {
return planAst.getCash();
} else {
return planBase.getTotalAmt();
}
} else if (account.getActAttr() == AccountAttributeEnum.PAY) {
LoanPropCntStat loanPropCntStat = loanDAO.statPlanBal(account.getPlanNo());
if (loanPropCntStat != null) {
return loanPropCntStat.getAmt().add(new Money("10000"));
}
}
} else {
//受让池 -- 非初始化查询
if (planAst.getStatus() != TaskStatusEnum.INIT) {
return planAst.getCash();
} else {
//初始化查询
return planBase.getTotalAmt();
}
}
return new Money(0);
}
@Override
public String trade(Account sourceAcct, Account targetAcct, Money money, String remark1) {
//条目组装
String enNo = WkSequenceUtil.Trade.genEntryNo();
return "mc" + enNo;
}
@Override
public TradeResult tradeRstQry(List<String> entryNos) {
TradeResult result = new TradeResult();
result.setPayInfoList(
TradeResult.mockDate(planCapitalOrderRepo.queryOrderListByOutAcptNo(TaskStatusEnum.WAITING, entryNos)));
return result;
}
@Override
public String type() {
return "mock";
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.service.wk.pay.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.abssqr.plat.common.facade.enums.AbssqrNoticeTypeEnum;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.integration.wk.WkPayIntegration;
import com.abssqr.plat.common.integration.wk.domain.Result;
import com.abssqr.plat.common.integration.wk.domain.WkBody;
import com.abssqr.plat.common.integration.wk.domain.config.WkPayConfig;
import com.abssqr.plat.common.integration.wk.domain.opr.OprRstHeader;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TdAccountInfo;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TdEntryInfo;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TdSourceAccountInfo;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TdTargetAccountInfo;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TradeInfo;
import com.abssqr.plat.common.integration.wk.domain.opr.request.trade.TradeList;
import com.abssqr.plat.common.integration.wk.domain.opr.response.AccountListResult;
import com.abssqr.plat.common.integration.wk.domain.opr.response.ProjectResult;
import com.abssqr.plat.common.integration.wk.domain.qry.QryRstHeader;
import com.abssqr.plat.common.integration.wk.domain.qry.response.BalanceResult;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.ComIdEnum;
import com.abssqr.plat.common.integration.wk.enums.EnTradeTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.PlatResultCodeEnum;
import com.abssqr.plat.common.integration.wk.enums.TradeTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAccountTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAcctKindEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAcctStatusEnum;
import com.abssqr.plat.common.integration.wk.enums.WkAcctTypeEnum;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.integration.wk.enums.WkResultCodeEnum;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil;
import com.abssqr.plat.common.integration.wk.utils.WkSequenceUtil.Trade;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.common.util.loggers.CommonLoggers;
import com.abssqr.plat.core.service.notice.AbssqrNoticeManager;
import com.general.system.common.model.Money;
import com.general.system.common.model.exception.BaseCommonException;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import com.general.system.common.util.VarChecker;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Set;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.core.service.wk.pay: WkPayOnLineServiceImpl.java, v 0.1 2019-12-15 14:38 bangis.wangdf Exp $
*/
@Service
public class WkPayOnLineServiceImpl extends AbsWkPayService {
private final static Logger LOGGER = CommonLoggers.WK_INTEGRATION;
@Autowired
private WkPayConfig wkPayConfig;
@Autowired
private WkPayIntegration wkPayIntegration;
@Autowired
private AbssqrNoticeManager abssqrNoticeManager;
@Override
public String type() {
return "prod";
}
/**
* 租户签约与维护
*
* @return
*/
@Override
public boolean project() {
Result<OprRstHeader, ProjectResult> result = wkPayIntegration.project(SequenceUtil.genWkSeqNo(),
wkPayConfig.getProjNo(), wkPayConfig.getProjName());
try {
VarChecker.checkNotNull(result, "创建支付平台租约号[{0}-{1}]失败-result=null", wkPayConfig.getProjNo(),
wkPayConfig.getProjName());
VarChecker.checkNotNull(result.getHeader(), "创建支付平台租约号[{0}-{1}]失败-result.getHeader=null",
wkPayConfig.getProjNo(), wkPayConfig.getProjName());
VarChecker.checkNotNull(result.getBody(), "创建支付平台租约号[{0}-{1}]失败-result.getBody=null",
wkPayConfig.getProjNo(),
wkPayConfig.getProjName());
} catch (BaseCommonException e) {
this.sendNotice(e.getMessage());
throw e;
}
return result.getHeader().getResultCode() == PlatResultCodeEnum.成功
&& result.getBody().getResultCode() == WkResultCodeEnum.成功;
}
/**
* 创建账户号
* 重复调用不会改天
*
* @return 返回支付平台虚拟号
*/
@Override
public WkAccount createAccount(String planNo, String planName, AccountAttributeEnum actAttr) {
WkAccount account = new WkAccount();
account.setAccountName(WkSequenceUtil.Account.genAccountName(TradeTypeEnum.放款, planName, actAttr));
account.setAccountNo(WkSequenceUtil.Account.genAccountNo(TradeTypeEnum.放款, planNo, actAttr));
account.setAcctKind(WkAcctKindEnum.对公);
account.setAcctType(WkAcctTypeEnum.放款账户);
account.setCustName(WkSequenceUtil.Account.genCustName(planName));
account.setCustNo(WkSequenceUtil.Account.genCustNo(planNo));
// 租户编号
account.setTenantNo(wkPayConfig.getProjNo());
List<WkAccount> accountList = CollectionUtil.newArrayList(account);
Result<OprRstHeader, AccountListResult> result = wkPayIntegration.account(SequenceUtil.genWkSeqNo(),
accountList);
try {
VarChecker.checkNotNull(result, "创建支付平台创建账户号[{0}}]失败-result=null", account);
VarChecker.checkNotNull(result.getHeader(), "创建支付平台创建账户号[{0}}]失败-result.getHeader()=null", account);
VarChecker.checkNotNull(result.getBody(), "创建支付平台创建账户号[{0}}]失败-result.getBody()=null", account);
VarChecker.checkEquals(result.getHeader().getResultCode(), PlatResultCodeEnum.成功,
"创建支付平台创建账户号[{0}}]失败-result.getHeader.result!=成功", account);
VarChecker.checkArgument(CollectionUtils.isNotEmpty(result.getBody().getAccountList()),
"创建支付平台创建账户号[{0}}]失败-result.getBody().getAccountList()()=null", account);
VarChecker.checkEquals(result.getBody().getAccountList().get(0).getStatus(), WkAcctStatusEnum.成功);
} catch (BaseCommonException e) {
this.sendNotice(e.getMessage());
throw e;
}
return account;
}
/**
* 查询账户余额
* 创建完虚拟号后再没有关联实际银行卡时result.getBody()=null
*
* @param accountNo
* @return
*/
@Override
public Money balance(String accountNo, WkChannelNoEnum channelNo) {
Result<QryRstHeader, BalanceResult> result = wkPayIntegration.balance(SequenceUtil.genWkSeqNo(), accountNo,
channelNo);
try {
VarChecker.checkNotNull(result, "查询账户余额[{0}}]失败-result=null", accountNo);
VarChecker.checkNotNull(result.getHeader(), "查询账户余额[{0}}]失败-result.getHeader()=null", accountNo);
VarChecker.checkNotNull(result.getBody(), "查询账户余额[{0}}]失败-result.getBody()=null", accountNo);
VarChecker.checkEquals(result.getHeader().getResultCode(), PlatResultCodeEnum.成功,
"查询账户余额[{0}}]失败-result.getHeader.result!=10000;{1}",
accountNo, result.getHeader().getResultMsg());
VarChecker.checkArgument(CollectionUtils.isNotEmpty(result.getBody().getBalanceList()),
"查询账户余额[{0}}]失败-没有查到余额",
accountNo);
} catch (BaseCommonException e) {
this.sendNotice(e.getMessage());
throw e;
}
return Money.createWithCent(result.getBody().getBalanceList().get(0).getBalance());
}
/**
* 只有放款逻辑
* 五矿支付接口返回状态只有受理成功与平台异常,
* 平台异常时无法保证资金是否会转让
*
* @param sourceAcct 源账号
* @param targetAcct 目标账号
* @param money
* @return 条目号
* @see Trade#genTradeNo()
*/
@Override
public String trade(Account sourceAcct, Account targetAcct, Money money, String remark1) {
VarChecker.checkEquals(sourceAcct.getActType(), AccountTypeEnum.PLAT_VIRTUAL);
TradeList tradeList = new TradeList();
List<TradeInfo> list = Lists.newArrayList();
TradeInfo tradeInfo = new TradeInfo();
// 受理单号
String tradeNo = SequenceUtil.genWkSeqNo(ComIdEnum.资产转让.getCode());
tradeInfo.setTradeNo(tradeNo);
tradeInfo.setTotalEntryNum(1L);
tradeInfo.setTradeTypeNo(TradeTypeEnum.放款);
//条目组装
String enNo = WkSequenceUtil.Trade.genEntryNo();
List<TdEntryInfo> entryList = Lists.newArrayList();
TdEntryInfo tdEntryInfo = new TdEntryInfo();
tdEntryInfo.setRemark1(remark1);
tdEntryInfo.setAmount(money.getCent());
//SourceTarget为平台账户时不能填
if (sourceAcct.getActType() == AccountTypeEnum.BANK) {
tdEntryInfo.setChannelNo(WkChannelNoEnum.getByCode(sourceAcct.getChannelNo()));
}
tdEntryInfo.setEntryNo(enNo);
tdEntryInfo.setEntryTypeNo(WkSequenceUtil.Trade.genEntryTypeNo(EnTradeTypeEnum.放款, 1));
tdEntryInfo.setEnTradeType(EnTradeTypeEnum.放款);
//账号组装
List<TdSourceAccountInfo> sourceAccountList = Lists.newArrayList();
TdSourceAccountInfo tdSourceAccountInfo = new TdSourceAccountInfo();
tdSourceAccountInfo.setLevel(1);
tdSourceAccountInfo.setAccountInfo(builderAccountInfo(sourceAcct));
sourceAccountList.add(tdSourceAccountInfo);
tdEntryInfo.setSourceAccountList(sourceAccountList);
List<TdTargetAccountInfo> targetAccountList = Lists.newArrayList();
TdTargetAccountInfo tdTargetAccountInfo = new TdTargetAccountInfo();
tdTargetAccountInfo.setLevel(1);
tdTargetAccountInfo.setAccountInfo(builderAccountInfo(targetAcct));
targetAccountList.add(tdTargetAccountInfo);
tdEntryInfo.setTargetAccountList(targetAccountList);
entryList.add(tdEntryInfo);
// 设置入账条目
tradeInfo.setEntryList(entryList);
// 组装交易信息
list.add(tradeInfo);
// 组装交易信息集合
tradeList.setTradeList(list);
try {
Result<OprRstHeader, WkBody> trade = wkPayIntegration.trade(SequenceUtil.genWkSeqNo(), tradeList);
if (trade != null) {
LogUtil.info(LOGGER, "五矿代理交易 - [{0}-{1}-{2}]", SequenceUtil.genWkSeqNo(), enNo,
trade.getHeader().getResultCode());
} else {
String msg = MessageUtil.formatMsg("五矿代理交易返回结果异常 - [{0}-{1}]", SequenceUtil.genWkSeqNo(), enNo);
LogUtil.warn(LOGGER, msg);
sendNotice(msg);
}
} catch (AbssqrBizException e) {
LogUtil.error(LOGGER, e, "ABS系统-内部异常 - [{0}-{1}]", SequenceUtil.genWkSeqNo(), enNo);
throw e;
} catch (Throwable e) {
LogUtil.error(LOGGER, e, "五矿代理交易返回网络等异常 - [{0}-{1}]", SequenceUtil.genWkSeqNo(), enNo);
}
return enNo;
}
/**
* 代理交易结果查询
* 只支持4 做查询
*
* @param entryNos
* @return TradeResult 可能为空
*/
@Override
public TradeResult tradeRstQry(List<String> entryNos) {
Result<QryRstHeader, TradeResult> result = wkPayIntegration.tradeRstQry(SequenceUtil.genWkSeqNo(), entryNos);
try {
VarChecker.checkNotNull(result, "代理交易结果查询[{0}}]失败-result=null", entryNos);
VarChecker.checkNotNull(result.getHeader(), "代理交易结果查询[{0}}]失败-result.getHeader()=null", entryNos);
VarChecker.checkNotNull(result.getBody(), "代理交易结果查询[{0}}]失败-result.getBody()=null", entryNos);
} catch (BaseCommonException e) {
this.sendNotice(e.getMessage());
throw e;
}
return result.getBody();
}
private TdAccountInfo builderAccountInfo(Account account) {
TdAccountInfo tdSourceAccount = new TdAccountInfo();
if (account.getActType() == AccountTypeEnum.BANK) {
tdSourceAccount.setAccountType(WkAccountTypeEnum.企业账户);
tdSourceAccount.setAccountNo(account.getActNo());
tdSourceAccount.setAccountName(account.getActName());
tdSourceAccount.setChannelNo(WkChannelNoEnum.getByCode(account.getChannelNo()));
tdSourceAccount.setBankName(account.getActBank());
tdSourceAccount.setProvince(account.getActProv());
tdSourceAccount.setCity(account.getActCity());
tdSourceAccount.setChannelNo(WkChannelNoEnum.getByCode(account.getChannelNo()));
} else {
tdSourceAccount.setAccountNo(account.getActNo());
tdSourceAccount.setAccountType(WkAccountTypeEnum.支付平台账号);
}
return tdSourceAccount;
}
private void sendNotice(String content) {
Set<String> receivers = abssqrNoticeManager.getAdminReceivers();
String bizTitle = "五矿返回结果异常告警";
String bizCode = "wk";
abssqrNoticeManager.sendSystemNotice(bizTitle, bizCode, AbssqrNoticeTypeEnum.WkPayManager, content, receivers);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.pay;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.general.system.common.model.BaseEntity;
import com.general.system.common.model.Money;
import java.util.Date;
/**
* 计划资金交易请求
* @author zhenxuan.luo
* @version com.abssqr.plat.core.share.pay: PlanCapitalRequest.java, v 0.1 2019-06-03 16:46 zhenxuan.luo Exp $
*/
public class PlanCapitalCreateRequest extends BaseEntity {
/**
* 业务编号
*/
private String bizNo;
/**
* 计划编号
*/
private String planNo;
/**
* 目标机构编号
*/
private String targetOrgCode;
/**
* 实付交易额
*/
private Money transAmt = new Money(0);
/**
* payableAmt 应付金额.
*/
private Money payableAmt = new Money(0);
/**
* 会计日期
*/
private Date accountDate;
/**
* 资金交易类型
*/
private PlanCapitalTransTypeEnum transType;
/**
* 备注
*/
private String memo;
public String getBizNo() {
return bizNo;
}
public void setBizNo(String bizNo) {
this.bizNo = bizNo;
}
public String getPlanNo() {
return planNo;
}
public void setPlanNo(String planNo) {
this.planNo = planNo;
}
public String getTargetOrgCode() {
return targetOrgCode;
}
public void setTargetOrgCode(String targetOrgCode) {
this.targetOrgCode = targetOrgCode;
}
public Money getTransAmt() {
return transAmt;
}
public void setTransAmt(Money transAmt) {
this.transAmt = transAmt;
}
public Date getAccountDate() {
return accountDate;
}
public void setAccountDate(Date accountDate) {
this.accountDate = accountDate;
}
public PlanCapitalTransTypeEnum getTransType() {
return transType;
}
public void setTransType(PlanCapitalTransTypeEnum transType) {
this.transType = transType;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public Money getPayableAmt() {
return payableAmt;
}
public void setPayableAmt(Money payableAmt) {
this.payableAmt = payableAmt;
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.pay;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalLog;
import org.springframework.beans.factory.InitializingBean;
/**
* 资金单交易完成后的接续处理接口
* @author zhenxuan.luo
* @version com.abssqr.plat.core.share.pay: PlanCapitalFinishProcess.java, v 0.1 2019-06-03 21:20 zhenxuan.luo Exp $
*/
public interface PlanCapitalFinishProcess extends InitializingBean{
/**
* 根据资金流水处理
*
* @param planCapitalLog
*/
void process(PlanCapitalLog planCapitalLog);
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.pay;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalLog;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.VarChecker;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* 资金单交易完成后的接续处理 工厂类
* @author zhenxuan.luo
* @version com.abssqr.plat.core.share.pay: PlanCapitalFinishProcessFactory.java, v 0.1 2019-06-03 21:21 zhenxuan.luo Exp $
*/
@Component
public class PlanCapitalFinishProcessFactory {
private final static Logger LOGGER = LoggerFactory.getLogger(PlanCapitalFinishProcessFactory.class);
private final Map<PlanCapitalTransTypeEnum, PlanCapitalFinishProcess> processMap = Maps.newHashMap();
public void registerProcess(PlanCapitalTransTypeEnum transType, PlanCapitalFinishProcess process) {
processMap.put(transType, process);
}
public void process(PlanCapitalLog planCapitalLog) {
VarChecker.checkNotNull(planCapitalLog);
PlanCapitalFinishProcess process = processMap.get(planCapitalLog.getTransType());
if (null == process) {
return;
}
LogUtil.info(LOGGER, "调用计划[{0}]资金订单[{1}]交易[{2}]后处理器", planCapitalLog.getPlanNo(), planCapitalLog.getSeqNo(),
planCapitalLog.getTransType());
process.process(planCapitalLog);
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.pay;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.general.system.common.model.BaseEntity;
import com.general.system.common.model.Money;
/**
* 资金订单操作结果
*
* @author zhenxuan.luo
* @version com.abssqr.plat.core.share.pay: PlanCapitalFinishRequest.java, v 0.1 2019-06-03 16:50 zhenxuan.luo Exp $
*/
public class PlanCapitalFinishRequest extends BaseEntity {
private String seqNo;
private String outAcptNo;
private String outTransNo;
private Money cfrmAmt = new Money(0);
private TaskStatusEnum res;
private String memo;
public String getSeqNo() {
return seqNo;
}
public void setSeqNo(String seqNo) {
this.seqNo = seqNo;
}
public String getOutAcptNo() {
return outAcptNo;
}
public void setOutAcptNo(String outAcptNo) {
this.outAcptNo = outAcptNo;
}
public String getOutTransNo() {
return outTransNo;
}
public void setOutTransNo(String outTransNo) {
this.outTransNo = outTransNo;
}
public Money getCfrmAmt() {
return cfrmAmt;
}
public void setCfrmAmt(Money cfrmAmt) {
this.cfrmAmt = cfrmAmt;
}
public TaskStatusEnum getRes() {
return res;
}
public void setRes(TaskStatusEnum res) {
this.res = res;
}
public String getMemo() {
return memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.pay;
import com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanClearingOrderItem;
import com.abssqr.plat.common.facade.enums.AccountTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransAcct;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.TaskStatusEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.org.OrganizationEntity;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalLog;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.model.convertor.PlanCapitalLogConvertor;
import com.abssqr.plat.common.model.domain.task.ctr.AstSyncTaskCtr;
import com.abssqr.plat.common.model.domain.task.ctr.ext.AstSyncTaskContext;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.clearing.PlanClearingOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalLogRepo;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo;
import com.abssqr.plat.common.model.seq.SequenceUtil;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.abssqr.plat.core.service.acct.AcctManager;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.abssqr.plat.core.share.process.PlanCapitalFinishChangeStage;
import com.general.system.common.model.Money;
import com.general.system.common.util.*;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 计划资金订单操作
*
* @author zhenxuan.luo
* @version PlanCapitalOrderManager.java, v 0.1 2019-06-03 16:43 zhenxuan.luo Exp $
*/
@Component
public class PlanCapitalOrderManager {
private final static Logger LOGGER = LoggerFactory.getLogger(PlanCapitalOrderManager.class);
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanCapitalLogRepo planCapitalLogRepo;
@Autowired
private PlanCapitalFinishProcessFactory planCapitalFinishProcessFactory;
@Autowired
private PlanCapitalFinishChangeStage planCapitalFinishChangeStage;
@Autowired
private AcctManager acctManager;
@Autowired
private WkPayManager wkPayManager;
@Autowired
private PlanClearingOrderRepo planClearingOrderRepo;
@Autowired
private PlanManager planManager;
@Autowired
private AstSyncTaskCtrRepo astSyncTaskCtrRepo;
/**
* 初始化资金订单
* 清算、分配统一支付交易
* @return
*/
public PlanCapitalOrder createCapitalOrder(PlanCapitalCreateRequest request) {
String seqNo = SequenceUtil.genSeqNo(request.getTransType().getCode());
PlanCapitalOrder newOrder = new PlanCapitalOrder();
newOrder.setPlanNo(request.getPlanNo());
newOrder.setBizNo(request.getBizNo());
newOrder.setSeqNo(seqNo);
newOrder.setTransAmt(request.getTransAmt());
newOrder.setPayableAmt(request.getPayableAmt());
newOrder.setAccountDate(request.getAccountDate());
// 交易时间
newOrder.setTransTime(SystemDateUtil.getSystemDate());
newOrder.setTransType(request.getTransType());
newOrder.setCntPtyCode(request.getTargetOrgCode());
// 差异金额
Money diffAmt = newOrder.getPayableAmt().subtract(newOrder.getTransAmt());
newOrder.setMemo(MessageUtil.formatMsg("[{0}]-[{1}]-计划[{2}]对手[{3}]: {4}-应付[{5}]-交易[{6}]-差异[{7}]",
seqNo, request.getAccountDate(), request.getPlanNo(), request.getTargetOrgCode(), request.getTransType().getCode(),
newOrder.getPayableAmt(), newOrder.getTransAmt(), diffAmt));
// 追加备注内容
if (ToolUtil.isNotEmpty(request.getMemo())){
newOrder.setMemo(newOrder.getMemo().concat(request.getMemo()));
}
newOrder.setStatus(TaskStatusEnum.INIT);
// 可执行时间
newOrder.setProcTime(SystemDateUtil.getSystemDate());
// 下次可执行时间
newOrder.setNextExecTime(SystemDateUtil.getSystemDate());
// 实际交易金额大于0 创建可交易支付单
if (newOrder.getTransAmt().isGreaterThanZero()){
planCapitalOrderRepo.insert(newOrder);
}else{
// 实际交易金额小于等于0 时 创建备份支付单 状态记忽略
newOrder.setStatus(TaskStatusEnum.IGNORE);
planCapitalOrderRepo.insertHis(newOrder);
}
return newOrder;
}
/**
* 处理资金订单
* @param planCapitalOrder
* @return
*/
public void processCapitalOrder(PlanCapitalOrder planCapitalOrder, Date curTime) {
VarChecker.checkArgument(!planCapitalOrder.getStatus().isFinish(), "计划[{0}]的支付单[{1}]已结束,不再进行处理",
planCapitalOrder.getPlanNo(), planCapitalOrder.getSeqNo());
if (planCapitalOrder.getStatus() != TaskStatusEnum.INIT) {
LogUtil.warn(LOGGER, "支付单状态非初始化,已经发起支付请求,不再重复处理 - [{0}]", planCapitalOrder.getSeqNo());
return;
}
// 填入账号
this.fillAccount(planCapitalOrder);
// 发起平台户
Account srcAcct = this.getAcctByType(planCapitalOrder, AccountTypeEnum.PLAT_VIRTUAL);
// 目的银行户
Account tgtAcct = this.getAcctByType(planCapitalOrder, AccountTypeEnum.BANK);
// 获取备注
String remark1 = this.getRemark(planCapitalOrder);
// 在线交易
String enNo = wkPayManager.trade(srcAcct, tgtAcct, planCapitalOrder.getTransAmt(),remark1);
planCapitalOrder.setOutAcptNo(enNo);
planCapitalOrder.setStatus(TaskStatusEnum.WAITING);
//发起交易系统时间
planCapitalOrder.setTransTime(SystemDateUtil.getSystemDate());
// 更新下一次执行时间增加5分钟后
planCapitalOrder.setNextExecTime(DateTimeUtil.addMinutes(curTime, AbsConfig.timeStampBuffer));
int refCnt = planCapitalOrderRepo.updateProcess(planCapitalOrder);
LogUtil.info(LOGGER, "支付单[{0}]受理成功[{1}],执行状态更新结果[{2}]", planCapitalOrder.getSeqNo(), enNo, refCnt);
}
/**
* 获取备注信息
* @param planCapitalOrder
* @return
*/
private String getRemark(PlanCapitalOrder planCapitalOrder) {
String result = null;
String planNo = planCapitalOrder.getPlanNo();
PlanBase planBase = planManager.getPlanFullByNo(planNo);
if (planBase.getPlanType() == PlanTypeEnum.SPV){
String managerOrgCode = ((OrganizationEntity) planBase).getManagerOrgCode();
AstSyncTaskCtr astSyncTaskCtr = astSyncTaskCtrRepo.getAstSyncTaskCtr(managerOrgCode);
if (astSyncTaskCtr != null) {
AstSyncTaskContext extData = astSyncTaskCtr.getExtData();
Map<String, Map<String, String>> capitalOrderRemarkMap = extData.getCapitalOrderRemarkMap();
result = Optional.ofNullable(capitalOrderRemarkMap.get(planNo)).map(map -> map.get(planCapitalOrder.getTransType().getCode())).orElse(null);
}
}
return result;
}
/**
* 处理完成(成功或者失败)
* @param planCapitalFinishRequest
* @return
*/
public PlanCapitalOrder finishCapitalOrder(PlanCapitalFinishRequest planCapitalFinishRequest) {
PlanCapitalOrder planCapitalOrder = planCapitalOrderRepo.lockBySeqNo(planCapitalFinishRequest.getSeqNo());
VarChecker.checkNotNull(planCapitalOrder, "支付单[{0}]不存在,或已经被处理", planCapitalFinishRequest);
planCapitalOrder.setOutTransNo(planCapitalFinishRequest.getOutTransNo());
// 完成系统时间
planCapitalOrder.setFinishTime(SystemDateUtil.getSystemDate());
planCapitalOrder.setCfrmAmt(planCapitalFinishRequest.getCfrmAmt());
planCapitalOrder.setStatus(planCapitalFinishRequest.getRes());
planCapitalOrder.setMemo(
MessageUtil.formatMsg("{0}-{1}", planCapitalOrder.getMemo(), planCapitalFinishRequest.getMemo()));
// 1、插入历史表
planCapitalOrderRepo.insertHis(planCapitalOrder);
// 如果成功,进一步处理
if (planCapitalOrder.getStatus() == TaskStatusEnum.SUCCESS) {
// 2、删除支付单据
planCapitalOrderRepo.deleteBySeqno(planCapitalOrder.getSeqNo(), planCapitalOrder.getPlanNo());
PlanCapitalLog planCapitalLog = PlanCapitalLogConvertor.buildPlanCapitalLog(planCapitalOrder);
planCapitalLogRepo.insert(planCapitalLog);
// 3、更新水位金额变化及登记流水
planCapitalFinishChangeStage.changeAstByCapitalOrder(planCapitalOrder);
// 4、针对不同交易场景 后续 特殊处理业务
planCapitalFinishProcessFactory.process(planCapitalLog);
} else {
//还原代理交易,重新支付
Date nextExecTime = DateTimeUtil.addSecond(SystemDateUtil.getSystemDate(), 5);
planCapitalOrderRepo.restoreCapitalOrder(nextExecTime, planCapitalFinishRequest.getSeqNo());
}
return planCapitalOrder;
}
/**
* 填充账号信息
* @param planCapitalOrder
* return 对手机构的放款户
*/
private void fillAccount(PlanCapitalOrder planCapitalOrder) {
// 查询计划 所有账户
List<Account> planAccounts = acctManager.getAllAcctByPlanNo(planCapitalOrder.getPlanNo(),
IEnumUtil.getEnumList(AccountTypeEnum.class));
// 源账户
Account planAcct = this.filterByAttr(planCapitalOrder.getTransType().getSrcAcct(),
planAccounts);
VarChecker.checkNotNull(planAcct, "资金操作[{0}]计划账户不能为空", planCapitalOrder);
// 对手机构所有账户
List<Account> cntAccounts = acctManager.getAllAcctByPlanNo(planCapitalOrder.getCntPtyCode(),
IEnumUtil.getEnumList(AccountTypeEnum.class));
// 目的账户
Account cntPtyAcct = this.filterByAttr(planCapitalOrder.getTransType().getDesAcct(),
cntAccounts);
VarChecker.checkNotNull(cntPtyAcct, "资金操作[{0}]找不到合适的对手方账号", planCapitalOrder);
planCapitalOrder.setPlanAcct(planAcct);
planCapitalOrder.setCntPtyAcct(cntPtyAcct);
}
private Account filterByAttr(PlanCapitalTransAcct transAcct, List<Account> accountList) {
Account target = null;
for (Account account : accountList) {
if (account.getActAttr() == transAcct.getAttribute()
&& account.getActType() == transAcct.getAccountType()) {
target = account;
break;
}
}
return target;
}
/**
* 按账户类型找账户
* @param capitalOrder
* @return
*/
private Account getAcctByType(PlanCapitalOrder capitalOrder, AccountTypeEnum type) {
if (capitalOrder.getPlanAcct().getActType() == type) {
return capitalOrder.getPlanAcct();
}
if (capitalOrder.getCntPtyAcct().getActType() == type) {
return capitalOrder.getCntPtyAcct();
}
throw new AbssqrBizException(MessageUtil.formatMsg("计划[{0}]交易单seqNo[{1}]没有匹配[{2}]的账户",
capitalOrder.getPlanNo(), capitalOrder.getSeqNo(), type.getCode()));
}
/**
* 查询计划当前未完成结算单及交易支付单的数量
* 报表前置条件
* @param planNo
* @return
*/
public int reportCheckCapitals(String planNo, Day orgDate) {
int count = 0;
// 结算单
List<PlanClearingOrderItem> clearOrder =
planClearingOrderRepo.queryByClearingOrderStat(planNo, TaskStatusEnum.INIT, orgDate.getStandardDate());
if (ToolUtil.isNotEmpty(clearOrder)){
count += clearOrder.size();
}
// 判断机构会计日不分类型支付单数量
count += planCapitalOrderRepo.getActiveCntByCondition(orgDate.getStandardDate(), planNo, null,
Lists.newArrayList(TaskStatusEnum.INIT, TaskStatusEnum.WAITING, TaskStatusEnum.IGNORE)).intValue();
return count;
}
/**
* 验证当前是否存在支付单
* 账户是否可以进行余额查询
* @return
*/
public boolean checkExistCapital(String planNo) {
// 查询当前正在进行中的支付单
Long cnt = planCapitalOrderRepo.getActiveCntByCondition(null, planNo, null,
Lists.newArrayList(TaskStatusEnum.INIT, TaskStatusEnum.WAITING));
// 判断 当前已有支付单进行则不进行余额查询
if (cnt > 0) {
LogUtil.info(LOGGER, "查询到[{0}条]支付任务" , cnt);
return true;
}
return false;
}
/**
* 验证当前是否存在支付单结算单
* 停止放款日放款户转还款户
* @return
*/
public boolean repayAcctCapital(String planNo) {
int count = 0;
// 查询所有结算单
List<PlanClearingOrderItem> clearOrder =
planClearingOrderRepo.queryByClearingOrderStat(planNo, TaskStatusEnum.INIT, null);
if (ToolUtil.isNotEmpty(clearOrder)){
count += clearOrder.size();
}
// 查询当前所有支付单
count += planCapitalOrderRepo.getActiveCntByCondition(null, planNo, null, null);
// 判断 当前已有支付单进行则不进行余额查询
if (count > 0) {
LogUtil.info(LOGGER, "查询到[{0}条]待结算或支付任务" , count);
return true;
}
return false;
}
}
\ No newline at end of file
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.process;
import cn.hutool.json.JSONUtil;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.enums.TransCodeEnum;
import com.abssqr.plat.common.facade.model.plan.PlanAlloc;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.model.trans.CapitalTrader;
import com.abssqr.plat.common.facade.model.trans.ChangeStageParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocHandleParam;
import com.abssqr.plat.common.model.enums.TraderTypeEnum;
import com.abssqr.plat.common.model.exception.AbssqrBizException;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.core.service.plan.PlanAcctTitleManager;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.MessageUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* 交易成功 处理计划资金水位
* @author hanfei
* @version $Id: PlanCapitalFinishChangeStage.java, v 0.1 2019-07-18 11:55 AM hanfei Exp $
*/
@Service
public class PlanCapitalFinishChangeStage {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private PlanAcctTitleManager planAcctTitleManager;
@Autowired
private PlanAllocRepo planAllocRepo;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private PlanRepo planRepo;
/**
* 更新水位金额变化 及登记流水
* @param capitalOrder
*/
public void changeAstByCapitalOrder(PlanCapitalOrder capitalOrder){
Date accountDate = capitalOrder.getAccountDate();
// 获取 交易码
PlanCapitalTransTypeEnum transType = capitalOrder.getTransType();
// 获取交易场景 对应的资金方向 匹配对应的水位变化类型 sub 或 add
StageChangeTypeEnum changeType = StageChangeTypeEnum.getChangeByFlow(transType.getFlowType());
LogUtil.info(logger, "计划[{0}]-对手[{1}]-资金单OutBizNo[{2}]-交易码[{3}]-水位变化[{4}]-capitalOrder={5}",
capitalOrder.getPlanNo(), capitalOrder.getCntPtyCode(),
capitalOrder.getOutTransNo(), capitalOrder.getTransType().getCode(), changeType.getCode(), capitalOrder);
// 更新水位金额变化 及登记流水
planAstManager.changePlanAst(accountDate, capitalOrder.getPlanNo(), (planAst, planAstLogList) -> {
// 分配兑付单独处理
if (transType.getTransCode() == TransCodeEnum.ALLOC){
// 1、构建水位变化流水 减少 水位金额 与 减少支付在途金额
planAstLogList.add(planAstManager.itemChangeStage(accountDate, planAst, TraderTypeEnum.INITIATOR,
changeType, capitalOrder.getCfrmAmt(), transType,
capitalOrder.getBizNo(), JSONUtil.toJsonStr(capitalOrder)));
// 2、 执行科目入账操作
this.allocCapitalOrderEntry(capitalOrder);
}else{
// 查询对手机构
PlanBase cntPtyPlan = planRepo.getPlanByNo(capitalOrder.getCntPtyCode());
// 构建交易双方及支付单上的类型
CapitalTrader capitalTrader = new CapitalTrader(planAst.getPlanNo(), planAst.getPlanType(),
cntPtyPlan.getPlanNo(), cntPtyPlan.getPlanType(), capitalOrder.getTransType());
// 其他结算支付交易完成处理水位
// 变化计划资产水位金额与待结算的支出收入金额 登记日志流水
planAstLogList.addAll(planAstManager.execChangeStageTwoWay(planAst,
ChangeStageParam.createParamByCapital(capitalTrader, changeType, capitalOrder)));
}
});
}
/**
* 针对分配兑付单据执行科目入账操作
* @param capitalOrder
*/
private void allocCapitalOrderEntry(PlanCapitalOrder capitalOrder) {
PlanAlloc alloc = planAllocRepo.getPlanAllocDetail(capitalOrder.getBizNo());
if (alloc == null) {
throw new AbssqrBizException(MessageUtil.formatMsg("计划分配兑付[{0}]对应的分配计划不存在", capitalOrder.getBizNo()));
}
PlanAllocHandleParam handleParam = new PlanAllocHandleParam();
handleParam.setAlloc(alloc);
handleParam.setOutTransNo(capitalOrder.getOutTransNo());
planAcctTitleManager.allocTitleEntry(handleParam, capitalOrder);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.core.share.process;
import cn.hutool.json.JSONUtil;
import com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum;
import com.abssqr.plat.common.facade.enums.StageChangeTypeEnum;
import com.abssqr.plat.common.facade.model.org.OrganizationEntity;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalLog;
import com.abssqr.plat.common.facade.model.trans.PlanClearingOrder;
import com.abssqr.plat.common.model.convertor.PlanClearingOrderConvert;
import com.abssqr.plat.common.model.enums.TraderTypeEnum;
import com.abssqr.plat.common.model.repo.clearing.PlanClearingOrderRepo;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.plan.PlanAstManager;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.abssqr.plat.core.service.plan.calc.PlanHandler;
import com.abssqr.plat.core.service.system.TimeStampUtil;
import com.abssqr.plat.core.share.pay.PlanCapitalFinishProcess;
import com.abssqr.plat.core.share.pay.PlanCapitalFinishProcessFactory;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.VarChecker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* 交易成功 购买资产 与支付应付利息 进行回转放逻辑操作
* @author hanfei
* @version $Id: PlanCapitalFinishReturnProcess.java, v 0.1 2019-07-18 11:55 AM hanfei Exp $
*/
@Service
public class PlanCapitalFinishReturnProcess implements PlanCapitalFinishProcess {
protected final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private PlanCapitalFinishProcessFactory planCapitalFinishProcessFactory;
@Autowired
private PlanClearingOrderRepo planClearingOrderRepo;
@Autowired
private PlanAstManager planAstManager;
@Autowired
private PlanManager planManager;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
/**
* 交易成功后进行 补充回转放交易支付单
* 修改回转放的实现逻辑
1、交易单成功后变更放款池水位余额
2.1、增加回转放结算单clearingOrder
2.2、变更水位记录待结算金额
* @param capitalLog
*/
@Override
public void process(PlanCapitalLog capitalLog) {
Date accountDate = capitalLog.getAccountDate();
// 查询放款池计划
OrganizationEntity organizationEntity = this.getSPVEntity(capitalLog);
// 获取当前装让系统会计日
Date trfDate = orgAcctDayComponent.getTrfAcctDay().getStandardDate();
boolean isNeedClr = PlanHandler.calcNeedClr(organizationEntity, trfDate);
if (!isNeedClr) {
LogUtil.info(logger, "放款池计划[{0}]不需要回收转付-OutBizNo[{1}]",
organizationEntity.getPlanNo(), capitalLog.getOutBizNo());
return ;
}
// 记录变更增加放款池SPV 计划水位 同时记回转放ClearingOrder
planAstManager.changePlanAst(accountDate, organizationEntity.getPlanNo(), (spvAst,spvAstLogList) -> {
/**
* 1 创建回转放结算单 ClearingOrder
* ClearingOrder的seqNo为上一笔交易的seqNo关联到上一次的支付交易单据
* transOrderNo 对应当前交易的bizNo
*/
PlanClearingOrder clearingOrder = PlanClearingOrderConvert.buildClearingOrder(capitalLog, TimeStampUtil.getCurrentBufferedTimestamp());
planClearingOrderRepo.createOrder(clearingOrder);
LogUtil.info(logger, "创建放款池计划回转放结算单:【{0}】", clearingOrder);
// 2 变更 增加 待结算金额 回转放 为资金流出
spvAstLogList.add(planAstManager.itemChangeStage(clearingOrder.getAccountDate(), spvAst, TraderTypeEnum.INITIATOR,
StageChangeTypeEnum.CLEAR, clearingOrder.getTransAmt(), capitalLog.getTransType(),
clearingOrder.getSeqNo(), JSONUtil.toJsonStr(clearingOrder)));
});
}
@Override
public void afterPropertiesSet() throws Exception {
/**
* 进行回转放
* 1、转让资产
* 2、支付应付利息
* 3、还款冲正 -- 暂时没有
*/
planCapitalFinishProcessFactory.registerProcess(PlanCapitalTransTypeEnum.BUY_AST, this);
planCapitalFinishProcessFactory.registerProcess(PlanCapitalTransTypeEnum.PAY_HANG_INTR, this);
// 暂时没有
// planCapitalFinishProcessFactory.registerProcess(PlanCapitalTransTypeEnum.REPO_REVERSE, this);
}
/**
* 获取放款池计划
* @param capitalLog
* @return
*/
protected OrganizationEntity getSPVEntity(PlanCapitalLog capitalLog) {
// 查询放款池计划
OrganizationEntity organizationEntity = planManager.getPlanFullByNo(capitalLog.getCntPtyCode());
VarChecker.checkNotNull(organizationEntity, "放款池计划[{0}]不存在,不是针对放款计划的打款-OutBizNo[{1}]",
capitalLog.getCntPtyCode(), capitalLog.getOutBizNo());
return organizationEntity;
}
}
......@@ -4,28 +4,25 @@ package com.abssqr.plat.test;
* Copyright (c) 2017-2018 All Rights Reserved.
*/
import cn.hutool.core.date.DateUtil;
import java.util.Date;
import com.abssqr.plat.biz.shared.handler.LoanAstBuyBackMatchHandler;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.AstSyncJobKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.BalanceCheckKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.BalanceReportKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.CapitalAstMatchKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanCapitalOrderResJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.AcctDateDAO;
import com.abssqr.plat.common.dal.sync.auto.dao.WkAbsMfsBillCtrDAO;
import com.abssqr.plat.common.facade.enums.YNEnum;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.model.domain.accounting.AcctDate;
import com.abssqr.plat.common.model.domain.job.JobControl;
import com.abssqr.plat.common.model.domain.task.ctr.AstSyncTaskCtr;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.acct.AcctDateRepo;
import com.abssqr.plat.common.model.repo.job.JobControlRepository;
import com.abssqr.plat.core.share.pay.PlanCapitalOrderManager;
import cn.hutool.core.date.DateUtil;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.SystemDateUtil;
import com.general.system.common.util.VarChecker;
import com.general.system.tool.util.ToolUtil;
import org.apache.commons.lang3.StringUtils;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -33,11 +30,6 @@ import org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.TestExecutionListeners;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
/**
* 想要使用Mockito,必须添加
*
......@@ -70,32 +62,10 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
@Autowired
private PlanCapitalOrderManager planCapitalOrderManager;
@Autowired
private PlanCapitalOrderResJob planCapitalOrderResJob;
@Autowired
private WkAbsMfsBillCtrDAO wkAbsMfsBillCtrDAO;
@Autowired
private AcctDateDAO acctDateDAO;
/**
* 支付单处理及查询结果
*
* @param capitalOrders
*/
protected void capitalOrderMock(List<PlanCapitalOrder> capitalOrders) {
if (ToolUtil.isEmpty(capitalOrders)) {
return;
}
for (PlanCapitalOrder capitalOrder : capitalOrders) {
if (capitalOrder == null) {
continue;
}
planCapitalOrderManager.processCapitalOrder(capitalOrder, DateTimeUtil.addMinutes(SystemDateUtil.getSystemDate(), -30));
}
// 执行查询
planCapitalOrderResJob.doExecute();
}
@Autowired
......@@ -170,13 +140,9 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
}
@SpyBean
private BalanceCheckKeeper balanceCheckKeeper;
@SpyBean
private AstSyncJobKeeper astSyncJobKeeper;
protected void mockBalanceCheckKeeper(Date date) {
Mockito.doReturn(date).when(balanceCheckKeeper).getCurrentStanderDate();
}
protected void mockAstSyncJobKeeper(Date date) {
Mockito.doReturn(date).when(astSyncJobKeeper).getCurrentStanderDate();
......@@ -189,11 +155,7 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
Mockito.doReturn(date).when(capitalAstMatchKeeper).getCurrentStanderDate();
}
@SpyBean
private BalanceReportKeeper balanceReportKeeper;
protected void mockBalanceReportKeeper(Date date) {
Mockito.doReturn(date).when(balanceReportKeeper).getCurrentStanderDate();
}
@SpyBean
private LoanAstBuyBackMatchHandler loanAstBuyBackMatchHandler;
......
package com.abssqr.plat.test.testUtils;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.AbstractKeeperNode;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.BalanceReportKeeper;
import java.util.Date;
public class test {
public static void main(String[] args) {
//Date deadLineTime = AbstractKeeperNode.getDeadLineTime(new Date(), "10 0 0");
//System.out.println(deadLineTime.toLocaleString());
}
}
package com.abssqr.plat.test.testlink.ast;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.abssqr.plat.biz.shared.dispatcher.TaskGroupService;
import com.abssqr.plat.biz.shared.dispatcher.capitalAssetMatch.PlanCapitalAssertMatchExecutor;
import com.abssqr.plat.biz.shared.dispatcher.capitalAssetMatch.PlanCapitalAssertMatchLoader;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherSplitor;
import com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanDailyJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanFundJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanPackJob;
import com.abssqr.plat.biz.shared.scheduler.job.sync.ast.ZLOriginalAstSyncJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.BizDataChangeDO;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.TitleTypeEnum;
import com.abssqr.plat.common.facade.model.plan.PlanAcctTitle;
import com.abssqr.plat.common.facade.model.plan.PlanAlloc;
import com.abssqr.plat.common.facade.model.plan.PlanAllocItem;
import com.abssqr.plat.common.facade.param.org.OrgEntityOprParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocEditParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocQryParam;
import com.abssqr.plat.common.facade.param.plan.alloc.sub.PlanAllocItemParam;
import com.abssqr.plat.common.facade.service.plan.PlanAllocService;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.domain.task.TrTask;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanAcctTitleRepo;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.wk.domain.sync.WkMfsSyncCtr;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.plat.web.controller.org.OrgEntityController;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.bpm.domain.result.ProcessAfterResult;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.core.common.constant.factory.ConstantFactory;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.util.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
public class CapitalAstMatchTest extends BaseAutoTests{
@Autowired
private OrgEntityController orgService;
@Autowired
private PlanFundJob planFundJob;
@Autowired
private PlanDailyJob planDailyJob;
@Autowired
private ChangeManager changeManager;
@Autowired
private PlanAllocService planAllocService;
@Autowired
private WkMfsAstSyncDispatcherLoader astSyncDispatcherLoader;
@Autowired
private WkMfsAstSyncDispatcherSplitor astSyncDispatcherSplitor;
@Autowired
private WkMfsAstSyncDispatcherExecutor astSyncExecutor;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private AbsConfig absConfig;
@Autowired
ZLOriginalAstSyncJob zlOriginalAstSyncJob;
@Autowired
CapitalAssertMatchJob capitalAssertMathJob;
@Autowired
PlanCapitalAssertMatchLoader planCapitalAssertMatchLoader;
@Autowired
PlanCapitalAssertMatchExecutor planCapitalAssertMatchExecutor;
@Autowired
PlanAllocRepo planAllocRepo;
@Autowired
PlanAcctTitleRepo planAcctTitleRepo;
@Autowired
PlanPackJob planPackJob;
@Autowired
PlanAstMatchDispatcherLoader planAstMatchLoader;
@Autowired
PlanAstMatchDispatcherExecutor planAstMatchExecutor;
@Autowired
AstTrTaskExecutor astTrTaskExecutor;
@Autowired
AstTrTaskLoader astTrTaskLoader;
@XTest(relatePath = "testlink/ast/capitalAstMatch/plan")
@Test(dataProvider = "YamlDataProvider", description = "创建并生效放款计划", priority = 1)
public void createPlanTestLink(ICase iCase, String acctDate, OrgEntityOprParam spvParam) {
super.validJobCtr(capitalAssertMathJob.getJobName());
ConstantFactory.me().securityLogin("administrator");
// 更新会计日期
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
// 首次设置会计日期为 项目成立日期 -1
Date strDate = format.parse(acctDate);
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
// 放款计划管理--------------------------------------------
orgService.edit(spvParam);
BizDataChangeDO spvBizData = bizDataChangeDAO.getByBizNoAndStatus(spvParam.getPlanNo(), "PENDING");
if(spvBizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult spvRes = new ProcessAfterResult();
spvRes.setBusinessKey(spvBizData.getChangeNo());
spvRes.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(spvRes);
}
// 生成默认分配计划
PlanAllocQryParam allocSpvParm = new PlanAllocQryParam();
allocSpvParm.setPlanNo(spvParam.getPlanNo());
planAllocService.getPlanAlloc(allocSpvParm);
// 投入资本到账--------------------------------------------
// 再次设置会计日期为 项目起息日
super.updateDate(DateTimeUtil.addDays(strDate, 1), OrgCodeEnum.ABS.getCode());
planDailyJob.doExecute();
} catch (ParseException e) {
throw new RuntimeException(e.getMessage());
}
}
//testOnly不要删除,testOnly是按照顺序执行
//@XTest(relatePath = "testlink/ast/capitalAstMatch/initData", testOnly={"initWKData_capitalAstMatch_case0001","initWKData_capitalAstMatch_case0002"})
@XTest(relatePath = "testlink/ast/capitalAstMatch/initData")
@Test(dataProvider = "YamlDataProvider", description = "同步五矿数据-初始化", priority = 2)
public void capitalAstMatchTest(ICase iCase, String acctDate,boolean unMatch,String spvNo,String orgCode,String layerNo,Integer allocAmt,boolean needTrans) {
absConfig.setWkxwDbName("mfsbaid");
absConfig.setWkxwSynonymPre(".");
absConfig.setWkxwRepayPlanSelf(true);
// 更新会计日期
DateFormat format = new SimpleDateFormat("yyyyMMdd");
LogUtil.info(logger, " ---- 查询数据");
try {
Date strDate = format.parse(acctDate);
super.updateDate(strDate, orgCode);
//PlanBase plan = planRepo.getPlanByNo(planNo);
//PlanBase spv = planRepo.getPlanByNo(spvNo);
// ----每日任务----
LogUtil.info(logger, " ---- 1 初始化水位");
// 调用接口-初始化水位
planFundJob.doExecute();
// 计划每日任务
LogUtil.info(logger, " ---- 2 计划每日任务");
//planDailyJob.doExecute();
// ----同步五矿数据----
zlOriginalAstSyncJob.doExecute();
LogUtil.info(logger, " ---- 3 同步五矿数据");
// astSyncDispatcherSplitor.setOrgCode(orgCode);
// astSyncDispatcherLoader.setOrgCode(orgCode);
List<WkMfsSyncCtr> syncNodes = astSyncDispatcherLoader.loadToDoNodes(
new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList(1L,Long.MAX_VALUE);
}
@Override
public void finish() {
}
}
, new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList();
}
@Override
public void finish() {
}
}
, 20);
for (WkMfsSyncCtr syncNode : syncNodes) {
astSyncExecutor.doExecute(syncNode);
}
//所有同步数据处理完成后,更新任务为成功
astSyncDispatcherSplitor.split();
//生成同步解绑任务
capitalAssertMathJob.doExecute();
//执行解绑/解绑匹配操作
List<CommonTask> commonTasks = planCapitalAssertMatchLoader.loadToDoNodes(100);
for(CommonTask commonTask:commonTasks){
planCapitalAssertMatchExecutor.execute(commonTask);
}
//申请兑付
if(unMatch){
List<PlanAlloc> planAllocs = planAllocRepo.queryByPlanNo(spvNo);
Assert.notEmpty(planAllocs,"放款计划"+spvNo+"不存在默认的分配计划");
PlanAlloc planAlloc = planAllocs.get(0);
PlanAllocEditParam planAllocEditParam = buildPlanAllocEditParam(planAlloc,spvNo,layerNo,allocAmt);
PlanTypeEnum planType = PlanTypeEnum.getByCode("SPV");
planAllocService.edit(planAllocEditParam, planType, true);
PlanAlloc planAllocDetail = planAllocRepo.getPlanAllocDetail(planAlloc.getAllocNo());
planAllocDetail.setApproveStatus(ApproveStatusEnum.PASSED);
planAllocRepo.addOrUpdate(planAllocDetail,true);
//生成 解绑/匹配 任务
capitalAssertMathJob.doExecute();
Thread.sleep(1000);
//执行解绑/解绑匹配操作
List<CommonTask> commonTasks2 = planCapitalAssertMatchLoader.loadToDoNodes(100);
for(CommonTask commonTask:commonTasks2){
planCapitalAssertMatchExecutor.execute(commonTask);
}
}
if(needTrans){
// 筛选资产包创建
LogUtil.info(logger, " ---- 4 筛选资产包创建");
planPackJob.doExecute();
// ----资产转让----
// 资产筛选
LogUtil.info(logger, " ---- 5 资产筛选");
planAstMatchLoader.setSleepTime(0);
List<CommonTask> commonTask = planAstMatchLoader.loadToDoNodes(10);
for(CommonTask task: commonTask){
if(task.getTaskType().equals(CommonTaskTypeEnum.PACK_MATCH)){
planAstMatchExecutor.doExecute(task);
}
}
// 资产转让
LogUtil.info(logger, " ---- 6 资产转让");
List<TrTask> trTasks = astTrTaskLoader.loadToDoNodes(10);
for (TrTask trTask : trTasks) {
astTrTaskExecutor.doExecute(trTask);
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
throw new RuntimeException(e.getMessage());
} finally {
checkDB(iCase);
clearDB(iCase);
}
}
//科目三兑付2500所有的资产全部兑付
private PlanAllocEditParam buildPlanAllocEditParam(PlanAlloc planAlloc,String spvNo,String layerNo,Integer allocAmt){
List<PlanAcctTitle> planAcctTitles = planAcctTitleRepo.getByEntityNo(spvNo);
PlanAcctTitle planAcctTitle= planAcctTitles.stream()
.filter(v->v.getTitleType()== TitleTypeEnum.PRIOR_INVESTED)
.filter(v->spvNo.equals(v.getPlanNo()))
.filter(v->layerNo.equals(v.getRefNo()))
.findFirst().get();
List<PlanAllocItem> planAllocItemList = planAlloc.getPlanAllocItemList();
List<PlanAllocItemParam> planAllocItemParams=new ArrayList<>();
if(CollectionUtils.isNotEmpty(planAllocItemList)){
PlanAllocItem planAllocItem = planAllocItemList.get(0);
PlanAllocItemParam planAllocItemParam=new PlanAllocItemParam();
planAllocItemParam.setTax(planAllocItem.getTax());
planAllocItemParam.setTitleNo(planAcctTitle.getTitleNo());
planAllocItemParam.setConfirmAmt(allocAmt.toString());
planAllocItemParam.setConfirmTaxAmt(planAllocItem.getTrialTaxAmt().getAmount().toPlainString());
planAllocItemParam.setTrialAmt(planAllocItem.getTrialAmt().getAmount().toPlainString());
planAllocItemParam.setTrialTaxAmt(planAllocItem.getTrialTaxAmt().getAmount().toPlainString());
planAllocItemParam.setOrder(planAllocItem.getOrder());
planAllocItemParams.add(planAllocItemParam);
planAllocItem.setConfirmAmt(planAllocItem.getTrialAmt());
planAllocItem.setConfirmTaxAmt(planAllocItem.getTrialTaxAmt());
}
PlanAllocEditParam planAllocEditParam=new PlanAllocEditParam();
planAllocEditParam.setPlanNo(planAlloc.getPlanNo());
planAllocEditParam.setAllocNo(planAlloc.getAllocNo());
planAllocEditParam.setPlanAllocItemParamList(planAllocItemParams);
return planAllocEditParam;
}
//是否发生转让
}
package com.abssqr.plat.test.testlink.ast;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherStarter;
import com.abssqr.plat.biz.shared.dispatcher.planAstStat.PlanAstStatTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.planAstStat.PlanAstStatTaskStarter;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskStarter;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.domain.task.TrTask;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.wk.domain.sync.WkMfsSyncCtr;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.List;
//@ActiveProfiles("dep")
public class TransferAstNormalTest extends BaseAutoTests {
private final static Logger LOGGER = LoggerFactory.getLogger(TransferAstNormalTest.class);
@Autowired
private PlanAstMatchDispatcherLoader planAstMatchLoader;
@Autowired
private PlanAstMatchDispatcherExecutor planAstMatchExecutor;
@Autowired
private PlanAstMatchDispatcherStarter planAstMatchStarter;
@Autowired
private AstTrTaskExecutor astTrTaskExecutor;
@Autowired
private PlanAstStatTaskStarter planStatTaskStarter;
@Autowired
private PlanAstStatTaskLoader planAstStatTaskLoader;
@Autowired
private PlanAstClearingStatHandler planAstClearingStatHandler;
@Autowired
private PlanAstStatTaskRepo planAstStatTask;
@Autowired
private AstTrTaskLoader astTrTaskLoader;
@Autowired
private AstTrTaskStarter astTrTaskStarter;
@XTest(relatePath = "testlink/ast/transferAst")
@Test(dataProvider = "YamlDataProvider", description = "资产转让")
public void transferAst(ICase iCase, String acctDate, String tfrPack, String trustPlanNo, Boolean flag,
WkMfsSyncCtr syncNode) {
super.invalidJobCtr(astTrTaskStarter.getName());
super.invalidJobCtr(planStatTaskStarter.getName());
super.invalidJobCtr(planAstMatchStarter.getName());
try {
// 更新会计日期
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
// 资产筛选
planAstMatchLoader.setSleepTime(0);
List<CommonTask> commonTask = planAstMatchLoader.loadToDoNodes(10);
Assert.assertTrue(commonTask.size() > 0, "没有捞到筛选任务");
for (CommonTask task : commonTask) {
if (task.getTaskType().equals(CommonTaskTypeEnum.PACK_MATCH)) {
planAstMatchExecutor.execute(task);
}
}
// 资产转让
List<TrTask> trTasks = astTrTaskLoader.loadToDoNodes(10);
Assert.assertTrue(trTasks.size() > 0, "没有捞到转让任务");
for (TrTask trTask : trTasks) {
astTrTaskExecutor.execute(trTask);
}
astTrTaskLoader.loadToDoNodes(10);
// 清算
planAstStatTaskLoader.loadToDoNodes(10);
PlanAstStatTask astStatTask = planAstStatTask.getPlanNo(trustPlanNo);
if (astStatTask != null) {
planAstClearingStatHandler.execute(astStatTask, "999912312359");
}
}catch (Exception e){
e.printStackTrace();
throw e;
}finally {
// super.validJobCtr(astTrTaskStarter.getName());
// super.validJobCtr(planStatTaskStarter.getName());
// super.validJobCtr(planAstMatchStarter.getName());
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
package com.abssqr.plat.test.testlink.link;
import com.abssqr.plat.biz.shared.dispatcher.TaskGroupService;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherSplitor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherStarter;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskLoader;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstStatTaskHandler;
import com.abssqr.plat.biz.shared.handler.PlanFundHandler;
import com.abssqr.plat.biz.shared.scheduler.job.ast.ZLFinSerFeeJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanDailyJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanFundJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanPackJob;
import com.abssqr.plat.biz.shared.scheduler.job.sync.ast.ZLOriginalAstSyncJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.BizDataChangeDO;
import com.abssqr.plat.common.dal.sync.auto.dao.WkAbsMfsBillCtrDAO;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.param.org.OrgEntityOprParam;
import com.abssqr.plat.common.facade.param.plan.PlanOprParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocQryParam;
import com.abssqr.plat.common.facade.service.plan.PlanAllocService;
import com.abssqr.plat.common.facade.service.plan.PlanService;
import com.abssqr.plat.common.model.domain.job.JobControl;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.domain.task.TrTask;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.wk.domain.sync.WkMfsSyncCtr;
import com.abssqr.plat.common.model.wk.repo.WkDhccBatchRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.plat.web.controller.org.OrgEntityController;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.bpm.domain.result.ProcessAfterResult;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.core.common.constant.factory.ConstantFactory;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
import org.testng.annotations.Test;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
//@ActiveProfiles("test")
public class PreRepayFeeNormalTest extends BaseAutoTests {
@Autowired
private PlanService planService;
@Autowired
private OrgEntityController orgService;
@Autowired
private PlanFundJob planFundJob;
@Autowired
private PlanDailyJob planDailyJob;
@Autowired
private PlanReportTaskExecutor reportExecutor;
@Autowired
private ChangeManager changeManager;
@Autowired
private AstTrTaskLoader astTrTaskLoader;
@Autowired
private PlanFundHandler planFundHandler;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanAllocService planAllocService;
@Autowired
private PlanAstMatchDispatcherLoader planAstMatchLoader;
@Autowired
private PlanAstMatchDispatcherExecutor planAstMatchExecutor;
@Autowired
private AstTrTaskExecutor astTrTaskExecutor;
@Autowired
private PlanAstStatTaskRepo planAstStatTask;
@Autowired
private PlanAstClearingStatHandler planAstStatHandler;
@Autowired
private WkMfsAstSyncDispatcherLoader astSyncDispatcherLoader;
@Autowired
private WkMfsAstSyncDispatcherSplitor astSyncDispatcherSplitor;
@Autowired
private WkMfsAstSyncDispatcherExecutor astSyncExecutor;
@Autowired
private WkMfsAstSyncDispatcherStarter astSyncStarter;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private ZLFinSerFeeJob zlFinSerFeeJob;
@Autowired
private PlanAstStatTaskHandler planAstStatTaskHandler;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanReportTaskLoader planLoader;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@Autowired
private PlanPackJob planPackJob;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@MockBean
private WkDhccBatchRepo wkDhccBatchRepo;
@Autowired
WkAbsMfsBillCtrDAO wkAbsMfsBillCtrDAO;
@Autowired
private AbsConfig absConfig;
@Autowired
ZLOriginalAstSyncJob zlOriginalAstSyncJob;
@XTest(relatePath = "testlink/link/plan")
@Test(dataProvider = "YamlDataProvider", description = "创建并生效计划", priority = 1)
public void createPlanTestLink(ICase iCase, String acctDate, String orgDate, PlanOprParam planParam, OrgEntityOprParam spvParam) {
//创建分区
autoPartition(OrgCodeEnum.WK1009.getCode());
ConstantFactory.me().securityLogin("administrator");
// 更新会计日期
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
// 首次设置会计日期为 项目成立日期 -1
Date strDate = format.parse(acctDate);
Date strOrgDate = format.parse(orgDate);
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
super.updateDate(strOrgDate, OrgCodeEnum.WK1009.getCode());
super.updateDate(strOrgDate, OrgCodeEnum.WK1011.getCode());
// 受让计划管理-->提交审批
LogUtil.info(logger, " ---- 1 受让池计划初始化及审批");
planService.edit(planParam);
BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(planParam.getPlanNo(), "PENDING");
if (bizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult result = new ProcessAfterResult();
result.setBusinessKey(bizData.getChangeNo());
result.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(result);
}
// 生成默认分配计划
LogUtil.info(logger, " ---- 2 生成默认分配计划");
PlanAllocQryParam allocParm = new PlanAllocQryParam();
allocParm.setPlanNo(planParam.getPlanNo());
planAllocService.getPlanAlloc(allocParm);
// 放款计划管理--------------------------------------------
LogUtil.info(logger, " ---- 1 放款池计划初始化及审批");
orgService.edit(spvParam);
BizDataChangeDO spvBizData = bizDataChangeDAO.getByBizNoAndStatus(spvParam.getPlanNo(), "PENDING");
if(spvBizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult spvRes = new ProcessAfterResult();
spvRes.setBusinessKey(spvBizData.getChangeNo());
spvRes.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(spvRes);
}
// 生成默认分配计划
PlanAllocQryParam allocSpvParm = new PlanAllocQryParam();
allocSpvParm.setPlanNo(spvParam.getPlanNo());
planAllocService.getPlanAlloc(allocSpvParm);
// 投入资本到账--------------------------------------------
// 再次设置会计日期为 项目起息日
super.updateDate(DateTimeUtil.addDays(strDate, 1), OrgCodeEnum.ABS.getCode());
planDailyJob.doExecute();
// 初始化水位,根据环境统一设置mock,默认mock金额为10000000000
// 执行余额查询
LogUtil.info(logger, " ---- 2 执行余额查询");
PlanBase planEntity = planRepo.getPlanByNo(planParam.getPlanNo());
planFundHandler.executeQueryBalance(planEntity, new Day(strDate).getTomorrow());
// 调用接口-初始化水位
planFundJob.doExecute();
// 校验数据
//checkDB(iCase);
} catch (ParseException e) {
e.printStackTrace();
}
}
//testOnly不要删除,testOnly是按照顺序执行
@XTest(relatePath = "testlink/link/preRepayFee",testOnly = {"normalPreRepay_notClear_case0001","preRepay_firstDay_notClear_case0006","preRepay_fundEqual_case0010","preRepay_adjTerm_case0012"})
@Test(dataProvider = "YamlDataProvider", description = "同步五矿数据-初始化", priority = 1)
public void preRepayFeeTest(ICase iCase, String acctDate, String planNo, String spvNo, String orgCode) {
// 更新会计日期
DateFormat format = new SimpleDateFormat("yyyyMMdd");
LogUtil.info(logger, " ---- 查询数据");
String astSyncStarterCtrl = astSyncStarter.getName();
JobControl astSyncCtrl = invalidJobCtr(astSyncStarterCtrl);
try {
// Date strDate = format.parse(acctDate);
// super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
// 设置五矿dayNext 数据完成标记
when(wkDhccBatchRepo.checkDataReady(Mockito.anyString(), Mockito.any())).thenReturn(true);
// 执行切换会计日
orgAcctDayComponent.acctDaySwitch();
// 转让会计日
Day strDate = orgAcctDayComponent.getTrfAcctDay();
PlanBase plan = planRepo.getPlanByNo(planNo);
PlanBase spv = planRepo.getPlanByNo(spvNo);
// 模型转换处理
LogUtil.info(logger, " ---- 2 模型转换处理");
absConfig.setWkxwDbName("mfsbaid");
absConfig.setWkxwSynonymPre(".");
absConfig.setWkxwRepayPlanSelf(true);
// astSyncDispatcherLoader.setOrgCode(orgCode);
List<WkMfsSyncCtr> syncNodes = astSyncDispatcherLoader.loadToDoNodes(
new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList(1L,Long.MAX_VALUE);
}
@Override
public void finish() {
}
}
, new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList(0L,0L);
}
@Override
public void finish() {
}
}
, 20);
for (WkMfsSyncCtr syncNode : syncNodes) {
astSyncExecutor.doExecute(syncNode);
}
//astSyncDispatcherSplitor.setOrgCode(orgCode);
//所有同步数据处理完成后,更新任务为成功
astSyncDispatcherSplitor.split();
// 计划每日任务
LogUtil.info(logger, " ---- 3 计划每日任务");
planDailyJob.doExecute();
// 筛选资产包创建
LogUtil.info(logger, " ---- 4 筛选资产包创建");
planPackJob.doExecute();
// ----资产转让----
// 资产筛选
LogUtil.info(logger, " ---- 5 资产筛选");
planAstMatchLoader.setSleepTime(0);
List<CommonTask> commonTask = planAstMatchLoader.loadToDoNodes(10);
for(CommonTask task: commonTask){
if(task.getTaskType().equals(CommonTaskTypeEnum.PACK_MATCH)){
planAstMatchExecutor.doExecute(task);
}
}
// 资产转让
LogUtil.info(logger, " ---- 6 资产转让");
List<TrTask> trTasks = astTrTaskLoader.loadToDoNodes(10);
for (TrTask trTask : trTasks) {
astTrTaskExecutor.doExecute(trTask);
}
// 金融服务费定时任务统计
LogUtil.info(logger, " ---- 6.1 金融服务费定时任务统计");
zlFinSerFeeJob.setZlOrgCode(orgCode);
zlFinSerFeeJob.doExecute();
// 清算
// 计划资产状态汇总
LogUtil.info(logger, " ---- 7 清算汇总");
planAstStatTaskHandler.handle(planNo, strDate);
planAstStatTaskHandler.handle(spvNo, strDate);
PlanAstStatTask astStatTask1 = planAstStatTask.getPlanNo(planNo);
if (astStatTask1 != null) {
astStatTask1.setStatus(OrgAstStatStatusEnum.PROCESS);
astStatTask1.setMinId(null);
planAstStatTask.updateTask(astStatTask1);
planAstStatHandler.execute(astStatTask1, "999912312359");
}
PlanAstStatTask astStatTask2 = planAstStatTask.getPlanNo(spvNo);
if (astStatTask2 != null) {
astStatTask2.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask2);
planAstStatHandler.execute(astStatTask2, "999912312359");
astStatTask2.setAccountDate(strDate.getStandardDate());
astStatTask2.setMinId(null);
astStatTask2.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask2);
planAstStatHandler.execute(astStatTask2, "999912312359");
}
// 结算任务处理
LogUtil.info(logger, " ---- 8 结算处理");
planAstClearingOrderHandler.handle(plan);
planAstClearingOrderHandler.handle(spv);
// wk交易调用
// 资金订单状态由wait-->succ, 记得修改next_exec_time <= sysdate
LogUtil.info(logger, " ---- 9 支付处理");
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(planNo);
capitalOrders.addAll(planCapitalOrderRepo.getInitListByPlanNo(spvNo));
super.capitalOrderMock(capitalOrders);
// 放款池可能会有回转放的结算单需要执行
planAstClearingOrderHandler.handle(spv);
List<PlanCapitalOrder> spvReturn = planCapitalOrderRepo.getInitListByPlanNo(spv.getPlanNo());
super.capitalOrderMock(spvReturn);
// 计划报表
LogUtil.info(logger, " ---- 11 计划报表");
List<CommonTask> tasks = planLoader.loadToDoNodes(20);
LogUtil.info(logger, " ---- 当前用例:" + iCase.getId() + "----");
while (tasks.size() > 0){
LogUtil.info(logger, " ---- 执行报表任务:");
for(CommonTask task: tasks){
if(ToolUtil.equals(task.getContext(), plan.getPlanNo())){
LogUtil.info(logger, " ---- 执行受让池计划报表任务:");
reportExecutor.doExecute(task);
}
}
for(CommonTask task: tasks){
if(ToolUtil.equals(task.getContext(), spv.getPlanNo())){
LogUtil.info(logger, " ---- 执行放款池计划报表任务:");
reportExecutor.doExecute(task);
}
}
tasks = planLoader.loadToDoNodes(20);
}
} catch (Throwable e) {
System.out.println(e.getMessage());
e.getMessage();
e.printStackTrace();
} finally {
// validJobCtr(astSyncCtrl);
// validJobCtr(trTaskCtrl);
checkDB(iCase);
// super.clearDB(iCase);
}
}
}
package com.abssqr.plat.test.testlink.plan;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanAstStatJob;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
public class PlanAstStatJobNormalTest extends BaseAutoTests {
@Autowired
private PlanAstStatJob planAstStatJob;
@XTest(relatePath = "testlink/plan/planAstStatJob")
@Test(dataProvider = "YamlDataProvider", description = "计划资产状态汇总")
public void stateJob(ICase iCase, String acctDate) {
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
// 执行任务
planAstStatJob.doExecute();
} finally {
// 校验数据
checkDB(iCase);
super.clearDB(iCase);
}
}
}
package com.abssqr.plat.test.testlink.plan;
import com.abssqr.plat.biz.shared.dispatcher.buyback.LoanAstBuyBackExecutor;
import com.abssqr.plat.biz.shared.dispatcher.buyback.LoanAstBuyBackLoader;
import com.abssqr.plat.biz.shared.dispatcher.buyback.LoanAstBuyBackStarter;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskLoader;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstStatTaskHandler;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.domain.task.TrTask;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.tool.util.ToolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
//@ActiveProfiles("test")
public class PlanBuyBackNormalTest extends BaseAutoTests {
@Autowired
private LoanAstBuyBackExecutor loanAstBuyBackExecutor;
@Autowired
private LoanAstBuyBackLoader loanAstBuyBackLoader;
@Autowired
private LoanAstBuyBackStarter loanAstBuyBackStarter;
@Autowired
private PlanAstStatTaskHandler planAstStatTaskHandler;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanAstClearingStatHandler clearingStatHandler;
@Autowired
private PlanAstStatTaskRepo planAstStatTask;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@Autowired
private PlanReportRepo planReportRepo;
@Autowired
private PlanReportTaskLoader planReportTaskLoader;
@Autowired
private PlanReportTaskExecutor planReportTaskExecutor;
@Autowired
private PlanRepo planRepo;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@XTest(relatePath = "testlink/plan/planBuyBack/buyback",
testOnly = { "plan_buy_back_tr_2002","plan_buy_back_tr_3002","plan_buy_back_tr_4002","plan_buy_back_tr_5002" })
@Test(dataProvider = "YamlDataProvider", description = "资产回购")
public void execute(ICase iCase, String acctDate, String planNo, String spvNo) throws ParseException {
try {
// 更新会计日期
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date strDate = format.parse(acctDate);
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
this.invalidJobCtr(loanAstBuyBackStarter.getName());
List<TrTask> trTasks = loanAstBuyBackLoader.loadToDoNodes(1);
loanAstBuyBackExecutor.execute(trTasks.get(0));
// ctr_task 更新succ
loanAstBuyBackLoader.loadToDoNodes(1);
// 清算
// 计划资产状态汇总
LogUtil.info(logger, " ---- 7 清算汇总");
planAstStatTaskHandler.handle(planNo, trfDate);
planAstStatTaskHandler.handle(spvNo, trfDate);
PlanAstStatTask astStatTask1 = planAstStatTask.getPlanNo(planNo);
if (astStatTask1 != null) {
astStatTask1.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask1);
clearingStatHandler.execute(astStatTask1, "999912312359");
}
PlanAstStatTask astStatTask2 = planAstStatTask.getPlanNo(spvNo);
if (astStatTask2 != null) {
clearingStatHandler.execute(astStatTask2, "999912312359");
astStatTask2.setAccountDate(strDate);
astStatTask2.setMinId(null);
astStatTask2.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask2);
clearingStatHandler.execute(astStatTask2, "999912312359");
}
// 结算任务处理
PlanBase plan = planRepo.getPlanByNo(planNo);
PlanBase spv = planRepo.getPlanByNo(spvNo);
LogUtil.info(logger, " ---- 8 结算处理");
planAstClearingOrderHandler.handle(plan);
planAstClearingOrderHandler.handle(spv);
// wk交易调用
// 资金订单状态由wait-->succ, 记得修改next_exec_time <= sysdate
LogUtil.info(logger, " ---- 9 支付处理");
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(planNo);
capitalOrders.addAll(planCapitalOrderRepo.getInitListByPlanNo(spvNo));
super.capitalOrderMock(capitalOrders);
// 放款池可能会有回转放的结算单需要执行
planAstClearingOrderHandler.handle(spv);
List<PlanCapitalOrder> spvReturn = planCapitalOrderRepo.getInitListByPlanNo(spv.getPlanNo());
super.capitalOrderMock(spvReturn);
// Item_default 初始化
planReportRepo.defaultRPT001Init(spv.getPlanNo(), strDate);
planReportRepo.defaultRPT001Init(plan.getPlanNo(), strDate);
LogUtil.info(logger, " ---- 10 回购后生成 计划报表");
List<CommonTask> tasks = planReportTaskLoader.loadToDoNodes(20);
while (tasks.size() > 0) {
for (CommonTask task : tasks) {
if (ToolUtil.equals(task.getContext(), planNo))
planReportTaskExecutor.doExecute(task);
}
for (CommonTask task : tasks) {
if (ToolUtil.equals(task.getContext(), spvNo))
planReportTaskExecutor.doExecute(task);
}
tasks = planReportTaskLoader.loadToDoNodes(20);
}
super.updateDate(DateTimeUtil.addDays(strDate, 1), OrgCodeEnum.ABS.getCode());
tasks = planReportTaskLoader.loadToDoNodes(20);
while (tasks.size() > 0) {
for (CommonTask task : tasks) {
if (ToolUtil.equals(task.getContext(), planNo))
planReportTaskExecutor.doExecute(task);
}
for (CommonTask task : tasks) {
if (ToolUtil.equals(task.getContext(), spvNo))
planReportTaskExecutor.doExecute(task);
}
tasks = planReportTaskLoader.loadToDoNodes(20);
}
} catch (Exception e) {
throw e;
} finally {
// 校验数据
super.checkDB(iCase);
// super.clearDB(iCase);
}
}
}
package com.abssqr.plat.test.testlink.plan;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanFundJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.AcctDateDAO;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
public class PlanFundJobNormalTest extends BaseAutoTests {
@Autowired
private PlanFundJob planFundJob;
@Autowired
private AcctDateDAO acctDateDAO;
@Autowired
private AbsConfig absConfig;
@XTest(relatePath = "testlink/plan/planFundJob")
@Test(dataProvider = "YamlDataProvider", description = "资金到账任务")
public void planFundJob(ICase iCase, String acctDate) {
// 更新会计日期
absConfig.setEnv("fun_test");
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
// 根据环境统一设置mock,默认mock金额为10000000000
// 调用接口
planFundJob.doExecute();
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
package com.abssqr.plat.test.testlink.plan;
import com.abssqr.plat.biz.shared.dispatcher.TaskGroupService;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherSplitor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherStarter;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskLoader;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstStatTaskHandler;
import com.abssqr.plat.biz.shared.handler.PlanFundHandler;
import com.abssqr.plat.biz.shared.scheduler.job.ast.ZLFinSerFeeJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanDailyJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanFundJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanPackJob;
import com.abssqr.plat.biz.shared.scheduler.job.sync.ast.ZLOriginalAstSyncJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.BizDataChangeDO;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.param.org.OrgEntityOprParam;
import com.abssqr.plat.common.facade.param.plan.PlanOprParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocQryParam;
import com.abssqr.plat.common.facade.service.plan.PlanAllocService;
import com.abssqr.plat.common.facade.service.plan.PlanService;
import com.abssqr.plat.common.model.domain.job.JobControl;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.domain.task.TrTask;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.wk.domain.sync.WkMfsSyncCtr;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.plat.web.controller.org.OrgEntityController;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.bpm.domain.result.ProcessAfterResult;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.core.common.constant.factory.ConstantFactory;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
//@ActiveProfiles("dev")
public class PlanReportNormalTest extends BaseAutoTests {
@Autowired
private PlanService planService;
@Autowired
private OrgEntityController orgService;
@Autowired
private PlanFundJob planFundJob;
@Autowired
private PlanDailyJob planDailyJob;
@Autowired
private PlanReportTaskExecutor reportExecutor;
@Autowired
private ChangeManager changeManager;
@Autowired
private AstTrTaskLoader astTrTaskLoader;
@Autowired
private PlanFundHandler planFundHandler;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanAllocService planAllocService;
@Autowired
private PlanAstMatchDispatcherLoader planAstMatchLoader;
@Autowired
private PlanAstMatchDispatcherExecutor planAstMatchExecutor;
@Autowired
private AstTrTaskExecutor astTrTaskExecutor;
@Autowired
private PlanAstStatTaskRepo planAstStatTask;
@Autowired
private PlanAstClearingStatHandler planAstStatHandler;
@Autowired
private WkMfsAstSyncDispatcherLoader astSyncDispatcherLoader;
@Autowired
private WkMfsAstSyncDispatcherSplitor astSyncDispatcherSplitor;
@Autowired
private WkMfsAstSyncDispatcherExecutor astSyncExecutor;
@Autowired
private WkMfsAstSyncDispatcherStarter astSyncStarter;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private ZLFinSerFeeJob zlFinSerFeeJob;
@Autowired
private PlanAstStatTaskHandler planAstStatTaskHandler;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanReportTaskLoader planLoader;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@Autowired
private PlanPackJob planPackJob;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@Autowired
private AbsConfig absConfig;
@Autowired
ZLOriginalAstSyncJob zlOriginalAstSyncJob;
@XTest(relatePath = "testlink/plan/planReport")
@Test(dataProvider = "YamlDataProvider", description = "创建并生效计划", priority = 1)
public void createPlanTestLink(ICase iCase, String acctDate, String planCash, PlanOprParam planParam, OrgEntityOprParam spvParam) {
ConstantFactory.me().securityLogin("administrator");
// 更新会计日期
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
// 首次设置会计日期为 项目成立日期 -1
Date strDate = format.parse(acctDate);
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
// 受让计划管理-->提交审批
LogUtil.info(logger, " ---- 1 计划初始化");
planService.edit(planParam);
BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(planParam.getPlanNo(), "PENDING");
if (bizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult result = new ProcessAfterResult();
result.setBusinessKey(bizData.getChangeNo());
result.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(result);
}
// 生成默认分配计划
LogUtil.info(logger, " ---- 3 生成默认分配计划");
PlanAllocQryParam allocParm = new PlanAllocQryParam();
allocParm.setPlanNo(planParam.getPlanNo());
planAllocService.getPlanAlloc(allocParm);
// 放款计划管理--------------------------------------------
orgService.edit(spvParam);
BizDataChangeDO spvBizData = bizDataChangeDAO.getByBizNoAndStatus(spvParam.getPlanNo(), "PENDING");
if(spvBizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult spvRes = new ProcessAfterResult();
spvRes.setBusinessKey(spvBizData.getChangeNo());
spvRes.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(spvRes);
}
// 生成默认分配计划
PlanAllocQryParam allocSpvParm = new PlanAllocQryParam();
allocSpvParm.setPlanNo(spvParam.getPlanNo());
planAllocService.getPlanAlloc(allocSpvParm);
// 投入资本到账--------------------------------------------
// 再次设置会计日期为 项目起息日
super.updateDate(DateTimeUtil.addDays(strDate, 1), OrgCodeEnum.ABS.getCode());
planDailyJob.doExecute();
// 初始化水位,根据环境统一设置mock,默认mock金额为10000000000
// 执行余额查询
LogUtil.info(logger, " ---- 2 执行余额查询");
PlanBase planEntity = planRepo.getPlanByNo(planParam.getPlanNo());
planFundHandler.executeQueryBalance(planEntity, new Day(strDate).getTomorrow());
// 校验数据
checkDB(iCase);
} catch (ParseException e) {
e.printStackTrace();
}
}
//testOnly不要删除,testOnly是按照顺序执行
@XTest(relatePath = "testlink/baseData1", testOnly={"initWKData_20190703","initWKData_20190704"})
@Test(dataProvider = "YamlDataProvider", description = "同步五矿数据-初始化", priority = 1)
public void dailyJobTest(ICase iCase, String acctDate, String planNo, String spvNo, String orgCode) {
absConfig.setWkxwDbName("mfsbaid");
absConfig.setWkxwSynonymPre(".");
absConfig.setWkxwRepayPlanSelf(true);
LogUtil.info(logger, " ---- 查询数据");
String astSyncStarterCtrl = astSyncStarter.getName();
JobControl astSyncCtrl = invalidJobCtr(astSyncStarterCtrl);
String trTaskStarterCtrl = astSyncStarter.getName();
JobControl trTaskCtrl = invalidJobCtr(trTaskStarterCtrl);
try {
Day strDate = new Day(acctDate);
// 更新会计日期
super.updateDate(strDate.getTomorrow().getStandardDate(), OrgCodeEnum.ABS.getCode());
// 对应机构日
super.updateDate(strDate.getStandardDate(), orgCode);
PlanBase plan = planRepo.getPlanByNo(planNo);
PlanBase spv = planRepo.getPlanByNo(spvNo);
// ----每日任务----
LogUtil.info(logger, " ---- 1 初始化水位");
// 调用接口-初始化水位
planFundJob.doExecute();
// 计划每日任务
LogUtil.info(logger, " ---- 2 计划每日任务");
planDailyJob.doExecute();
// ----同步五矿数据----
zlOriginalAstSyncJob.doExecute();
LogUtil.info(logger, " ---- 3 同步五矿数据");
// astSyncDispatcherLoader.setOrgCode(orgCode);
List<WkMfsSyncCtr> syncNodes = astSyncDispatcherLoader.loadToDoNodes(
new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList(1L, 9999999L);
}
@Override
public void finish() {
}
}
, new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList();
}
@Override
public void finish() {
}
}
, 20);
for (WkMfsSyncCtr syncNode : syncNodes) {
astSyncExecutor.doExecute(syncNode);
}
// astSyncDispatcherSplitor.setOrgCode(orgCode);
//所有同步数据处理完成后,更新任务为成功
astSyncDispatcherSplitor.split();
// 筛选资产包创建
LogUtil.info(logger, " ---- 4 筛选资产包创建");
planPackJob.doExecute();
// ----资产转让----
// 资产筛选
LogUtil.info(logger, " ---- 5 资产筛选");
planAstMatchLoader.setSleepTime(0);
List<CommonTask> commonTask = planAstMatchLoader.loadToDoNodes(10);
for(CommonTask task: commonTask){
if(task.getTaskType().equals(CommonTaskTypeEnum.PACK_MATCH)){
planAstMatchExecutor.doExecute(task);
}
}
// 资产转让
LogUtil.info(logger, " ---- 6 资产转让");
List<TrTask> trTasks = astTrTaskLoader.loadToDoNodes(10);
for (TrTask trTask : trTasks) {
astTrTaskExecutor.doExecute(trTask);
}
// 金融服务费定时任务统计
LogUtil.info(logger, " ---- 6.1 金融服务费定时任务统计");
zlFinSerFeeJob.setZlOrgCode("1009");
zlFinSerFeeJob.doExecute();
// 清算
// 计划资产状态汇总
LogUtil.info(logger, " ---- 7 清算汇总");
planAstStatTaskHandler.handle(planNo, strDate);
planAstStatTaskHandler.handle(spvNo, strDate);
PlanAstStatTask astStatTask1 = planAstStatTask.getPlanNo(planNo);
if (astStatTask1 != null) {
astStatTask1.setStatus(OrgAstStatStatusEnum.PROCESS);
astStatTask1.setMinId(null);
planAstStatTask.updateTask(astStatTask1);
planAstStatHandler.execute(astStatTask1, "999912312359");
}
PlanAstStatTask astStatTask2 = planAstStatTask.getPlanNo(spvNo);
if (astStatTask2 != null) {
planAstStatHandler.execute(astStatTask2, "999912312359");
astStatTask2.setAccountDate(strDate.getStandardDate());
astStatTask2.setMinId(null);
astStatTask2.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask2);
planAstStatHandler.execute(astStatTask2, "999912312359");
}
// 结算任务处理
LogUtil.info(logger, " ---- 8 结算处理");
planAstClearingOrderHandler.handle(plan);
planAstClearingOrderHandler.handle(spv);
// wk交易调用
// 资金订单状态由wait-->succ, 记得修改next_exec_time <= sysdate
LogUtil.info(logger, " ---- 9 支付处理");
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(planNo);
capitalOrders.addAll(planCapitalOrderRepo.getInitListByPlanNo(spvNo));
super.capitalOrderMock(capitalOrders);
// 放款池可能会有回转放的结算单需要执行
planAstClearingOrderHandler.handle(spv);
List<PlanCapitalOrder> spvReturn = planCapitalOrderRepo.getInitListByPlanNo(spv.getPlanNo());
super.capitalOrderMock(spvReturn);
// 计划报表
LogUtil.info(logger, " ---- 11 计划报表");
List<CommonTask> tasks = planLoader.loadToDoNodes(20);
LogUtil.info(logger, " ---- 当前用例:" + iCase.getId() + "----");
while (tasks.size() > 0){
LogUtil.info(logger, " ---- 执行报表任务:");
for(CommonTask task: tasks){
if(ToolUtil.equals(task.getContext(), "lenderCode001")){
LogUtil.info(logger, " ---- 执行放款池计划报表任务:");
reportExecutor.doExecute(task);
}
}
for(CommonTask task: tasks){
if(ToolUtil.equals(task.getContext(), "testTrustPlanNo001")){
LogUtil.info(logger, " ---- 执行受让池计划报表任务:");
reportExecutor.doExecute(task);
}
}
tasks = planLoader.loadToDoNodes(20);
}
} catch (Throwable e) {
e.getMessage();
e.printStackTrace();
} finally {
// validJobCtr(astSyncCtrl);
// validJobCtr(trTaskCtrl);
checkDB(iCase);
// super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job;
import com.abssqr.plat.biz.shared.scheduler.job.plan.LenderOrgCapitalJob;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.ParseException;
/**
*
* @author hanfei
* @version $Id: LenderOrgCapitalJobTest.java, v 0.1 2019-12-13 7:29 PM hanfei Exp $
*/
public class LenderOrgCapitalJobTest extends BaseAutoTests {
@Autowired
private LenderOrgCapitalJob lenderOrgCapitalJob;
@XTest(relatePath = "unittest/job/LenderOrgCapital")
@Test(dataProvider = "YamlDataProvider", description = "放款户转还款户 ")
public void jobTest(ICase iCase, String strDate) throws ParseException {
try {
// 更新会计日期
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
lenderOrgCapitalJob.doExecute();
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanAstStatJob;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.core.service.system.TimeStampUtil;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.common.util.SystemDateUtil;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
/**
* 清算流水汇总
* @author hanfei
* @version $Id: PlanAstClearingOrderJobTest.java, v 0.1 2019-09-12 5:56 PM hanfei Exp $
*/
//@ActiveProfiles("dev")
public class PlanAstClearLogStatTest extends BaseAutoTests {
@Autowired
private PlanAstClearingStatHandler planAstClearingStatHandler;
@Autowired
private PlanAstStatTaskRepo planAstStatTaskRepo;
@Autowired
private PlanAstStatJob planAstStatJob;
@XTest(relatePath = "unittest/job/clearLog")
@Test(dataProvider = "YamlDataProvider", description = "测试结算单处理逻辑")
public void clearingOrder(ICase iCase, String planNo) {
try {
int count = planAstStatTaskRepo.updateTaskExec(SystemDateUtil.getSystemDate(),
"test",
Lists.newArrayList(planNo));
PlanAstStatTask node = planAstStatTaskRepo.getPlanNo(planNo);
String execTms = TimeStampUtil.getCurrentBufferedTimestamp();
planAstClearingStatHandler.execute(node, execTms);
// // 执行切换
// planAstStatJob.execute(null);
// planAstStatTaskRepo.updateTaskExec(SystemDateUtil.getSystemDate(),
// "test",
// Lists.newArrayList(planNo));
// node = planAstStatTaskRepo.getPlanNo(planNo);
// execTms = TimeStampUtil.getCurrentBufferedTimestamp();
// planAstClearingStatHandler.execute(node, execTms);
} finally {
// 校验数据
checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanAstClearingOrderJob;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
/**
*
* @author hanfei
* @version $Id: PlanAstClearingOrderJobTest.java, v 0.1 2019-09-12 5:56 PM hanfei Exp $
*/
public class PlanAstClearingOrderJobTest extends BaseAutoTests {
@Autowired
private PlanAstClearingOrderJob planAstClearingOrderJob;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@XTest(relatePath = "unittest/job/clearingOrder")
@Test(dataProvider = "YamlDataProvider", description = "测试结算单处理逻辑")
public void clearingOrder(ICase iCase) {
/**
* 测试结算单处理场景
* 1、放款池计划
* 1.1 放款终止日 停止支付 当交易单据类型资金流出 并且 停止支付时 只更新结算单状态 不进行支付操作
* 1.2 未转让交易 资金流入时 增加水位 -- 可交易金额大于零 -- 水位金额cover 交易金额
* 1.3 未转让交易 资金流入时 增加水位 -- 可交易金额小于零 -- 水位余额不足 直接将结算单更新为, 成功 SUCCESS
* 1.4 未转让交易 资金流入时 增加水位 -- 可交易金额大于零 -- 当实际交易金额小于结算单交易金额进行拆支付交易单
* 1.5 支付应付利息-放款冲正-购买资产-回转放的结算单处理
* 2、受让池计划
* 1.1 未转让交易 资金流入时 增加水位 -- 可交易金额大于零 -- 水位金额cover 交易金额
* 1.2 未转让交易 资金流入时 增加水位 -- 可交易金额大于零 -- 当实际交易金额小于结算单交易金额进行拆支付交易单
* 1.3 未转让交易 资金流入时 增加水位 -- 水位余额不足 直接将结算单更新为 成功 SUCCESS
*/
try {
planAstClearingOrderJob.doExecute();
// planAstClearingOrderHandler.handle();
} finally {
// 校验数据
checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.List;
/**
* 资金交易单查询结果 认为调整支付单金额 水位金额校验异常
* @author hanfei
* @version $Id: PlanCapitalOrderResErrorJobTest.java, v 0.1 2019-09-06 11:26 AM hanfei Exp $
*/
public class PlanCapitalOrderResErrorJobTest extends BaseAutoTests {
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@XTest(relatePath = "unittest/job/capitalOrderRes/error")
@Test(dataProvider = "YamlDataProvider", description = "认为修改支付单金额交易单查询结果执行失败")
public void capitalOrder(ICase iCase, String planNo, String acctDate) {
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
// 资金订单状态由wait-->succ, 记得修改next_exec_time <= sysdate
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(planNo);
// 执行支付单及查询支付单
super.capitalOrderMock(capitalOrders);
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job.keeper;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.BalanceCheckKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.sync.ast.ZLOriginalAstSyncJob;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
*
* @author xiachenxiang
* @version com.abssqr.plat.test.unittest.job: BalanceCheckKeeperTest.java, v 0.1 2019-10-08 11:41 AM xiachenxiang Exp $
*/
public class BalanceCheckKeeperTest extends BaseAutoTests {
@Autowired
private BalanceCheckKeeper balanceCheckKeeper;
@Autowired
private ZLOriginalAstSyncJob zlOriginalAstSyncJob;
@XTest(relatePath = "unittest/job/balanceCheckKeeper")
@Test(dataProvider = "YamlDataProvider", description = "余额校验")
public void jobTest(ICase iCase, String strDate) throws ParseException {
try {
// 更新会计日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(strDate);
updateDate(sdf2.parse(strDate), OrgCodeEnum.ABS.getCode());
mockBalanceCheckKeeper(date);
validJobCtr(zlOriginalAstSyncJob.getJobName());
balanceCheckKeeper.execute(date);
invalidJobCtr(zlOriginalAstSyncJob.getJobName());
}catch (Exception e){
e.printStackTrace();
}finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
\ No newline at end of file
package com.abssqr.plat.test.unittest.job.keeper;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.BalanceReportKeeper;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class BalanceReportKeeperTest extends BaseAutoTests {
@Autowired
private BalanceReportKeeper balanceReportKeeper;
@XTest(relatePath = "unittest/job/BalanceReportKeeper")
@Test(dataProvider = "YamlDataProvider", description = "每日十点余额通知")
public void jobTest(ICase iCase, String strDate) {
try {
// 更新会计日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(strDate);
mockBalanceReportKeeper(date);
balanceReportKeeper.execute(date);
} catch (ParseException e) {
throw new RuntimeException(e.getMessage());
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job.keeper;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.CapitalOrderKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanCapitalOrderJob;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author xiachenxiang
* @version com.abssqr.plat.test.unittest.job: CapitalOrderKeeperTest.java, v 0.1 2019-09-29 11:45 AM xiachenxiang Exp $
*/
public class CapitalOrderKeeperTest extends BaseAutoTests {
@Autowired
private CapitalOrderKeeper capitalOrderKeeper;
@Autowired
private PlanCapitalOrderJob planCapitalOrderJob;
@XTest(relatePath = "unittest/job/capitalOrderKeeper")
@Test(dataProvider = "YamlDataProvider", description = "资产同步监控任务")
public void jobTest(ICase iCase, String strDate) throws ParseException {
// 更新会计日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(strDate);
updateDate(date, OrgCodeEnum.ABS.getCode());
try {
validJobCtr(planCapitalOrderJob.getJobName());
capitalOrderKeeper.execute(date);
invalidJobCtr(planCapitalOrderJob.getJobName());
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job.keeper;
import com.abssqr.plat.biz.shared.dispatcher.planAstStat.PlanAstStatTaskStarter;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.PlanAstStatJobKeeper;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author xiachenxiang
* @version com.abssqr.plat.test.unittest.job: PlanAstStatJobKeeper.java, v 0.1 2019-09-29 3:01 PM xiachenxiang Exp $
*/
public class PlanAstStatJobKeeperTest extends BaseAutoTests {
@Autowired
private PlanAstStatJobKeeper planAstStatJobKeeper;
@Autowired
private PlanAstStatTaskStarter planAstStatTaskStarter;
@XTest(relatePath = "unittest/job/planAstStatJobKeeper")
@Test(dataProvider = "YamlDataProvider", description = "放款计划统计任务监控")
public void jobTest(ICase iCase, String strDate) throws ParseException {
try {
// 更新会计日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(strDate);
updateDate(date, OrgCodeEnum.ABS.getCode());
validJobCtr(planAstStatTaskStarter.getName());
planAstStatJobKeeper.execute(date);
invalidJobCtr(planAstStatTaskStarter.getName());
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.job;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.List;
/**
* 资金交易单查询结果成功后续处理
* @author hanfei
* @version $Id: planCapitalOrderResJobTest.java, v 0.1 2019-09-06 11:26 AM hanfei Exp $
*/
public class planCapitalOrderResJobTest extends BaseAutoTests {
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@Autowired
private PlanRepo planRepo;
@XTest(relatePath = "unittest/job/capitalOrderRes")
@Test(dataProvider = "YamlDataProvider", description = "交易单查询结果")
public void capitalOrder(ICase iCase, String planNo, String acctDate) {
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
/**
* 先处理结算
*/
planAstClearingOrderHandler.handle(planRepo.getPlanByNo(planNo));
// 资金订单状态由wait-->succ, 记得修改next_exec_time <= sysdate
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(planNo);
// 执行支付单及查询支付单
super.capitalOrderMock(capitalOrders);
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.plan;
import cn.hutool.core.date.DateUtil;
import com.abssqr.plat.biz.shared.handler.PlanFundHandler;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.BizDataChangeDO;
import com.abssqr.plat.common.facade.model.plan.PlanAlloc;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.param.plan.PlanOprParam;
import com.abssqr.plat.common.facade.service.plan.PlanService;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.bpm.domain.result.ProcessAfterResult;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.util.VarChecker;
import com.general.system.core.common.constant.factory.ConstantFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 追加投资结构
* @author xiachenxiang
* @version com.abssqr.plat.test.unittest.plan: PlanAppendStructure.java, v 0.1 2019-11-13 10:29 AM xiachenxiang Exp $
*/
public class PlanAppendStructureTest extends BaseAutoTests {
@Autowired
private PlanService planService;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private ChangeManager changeManager;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanFundHandler planFundHandler;
@Autowired
private PlanAllocRepo planAllocRepo;
@XTest(relatePath = "unittest/plan/planAppendTest/planAdd")
@Test(dataProvider = "YamlDataProvider", description = "计划新增", priority = 1)
public void create(ICase iCase, String acctDate, PlanOprParam planParam, List<LinkedHashMap> allocCheckList, List<LinkedHashMap> itemCheckList) {
ConstantFactory.me().securityLogin("administrator");
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
planService.edit(planParam);
BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(planParam.getPlanNo(), "PENDING");
if (bizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult result = new ProcessAfterResult();
result.setBusinessKey(bizData.getChangeNo());
result.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(result);
}
// 执行余额查询
PlanBase planEntity = planRepo.getPlanByNo(planParam.getPlanNo());
planFundHandler.executeQueryBalance(planEntity, trfDate);
List<PlanAlloc> planAllocs = planAllocRepo.queryByPlanNo(planParam.getPlanNo());
List<Date> clearDatelist = planAllocs.stream().map(PlanAlloc::getClearDate).collect(Collectors.toList());
List<Date> checkDatelist = allocCheckList.stream().map(item -> {
return DateUtil.parse(String.valueOf(item.get("payDate")));
}).collect(Collectors.toList());
// 校验分配计划
VarChecker.checkEquals(clearDatelist, checkDatelist);
// 校验分配计划数量
planAllocs.sort(Comparator.comparing(PlanAlloc::getClearDate));
List<Integer> allocItemList = planAllocs.stream().map(item -> {
return item.getPlanAllocItemList().size();
}).collect(Collectors.toList());
List<Integer> allocItemCheckList = itemCheckList.stream().map(item -> {
return (Integer) item.get("cnt");
}).collect(Collectors.toList());
VarChecker.checkEquals(allocItemList, allocItemCheckList);
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
@XTest(relatePath = "unittest/plan/planAppendTest/planAppend")
@Test(dataProvider = "YamlDataProvider", description = "追加投资结构", priority = 2)
public void append(ICase iCase, String acctDate, PlanOprParam planParam, List<LinkedHashMap> allocCheckList, List<LinkedHashMap> itemCheckList) {
ConstantFactory.me().securityLogin("administrator");
// 更新会计日期
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
planService.edit(planParam);
BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(planParam.getPlanNo(), "PENDING");
if (bizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult result = new ProcessAfterResult();
result.setBusinessKey(bizData.getChangeNo());
result.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(result);
}
// 执行余额查询
PlanBase planEntity = planRepo.getPlanByNo(planParam.getPlanNo());
planFundHandler.executeQueryBalance(planEntity, trfDate);
List<PlanAlloc> planAllocs = planAllocRepo.queryByPlanNo(planParam.getPlanNo());
List<Date> clearDatelist = planAllocs.stream().map(PlanAlloc::getClearDate).collect(Collectors.toList());
List<Date> checkDatelist = allocCheckList.stream().map(item -> {
return DateUtil.parse((String) item.get("payDate"));
}).collect(Collectors.toList());
// 校验分配计划
VarChecker.checkEquals(clearDatelist, checkDatelist);
// 校验分配计划数量
planAllocs.sort(Comparator.comparing(PlanAlloc::getClearDate));
List<Integer> allocItemList = planAllocs.stream().map(item -> {
return item.getPlanAllocItemList().size();
}).collect(Collectors.toList());
List<Integer> allocItemCheckList = itemCheckList.stream().map(item -> {
return (Integer) item.get("cnt");
}).collect(Collectors.toList());
VarChecker.checkEquals(allocItemList, allocItemCheckList);
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.test.unittest.plan;
import cn.hutool.core.date.DateUtil;
import com.abssqr.plat.biz.shared.handler.PlanFundHandler;
import com.abssqr.plat.common.dal.mysql.auto.dao.AcctDateDAO;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.BizDataChangeDO;
import com.abssqr.plat.common.facade.model.plan.PlanAlloc;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.param.plan.PlanOprParam;
import com.abssqr.plat.common.facade.service.plan.PlanService;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanAllocRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.bpm.domain.result.ProcessAfterResult;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.util.VarChecker;
import com.general.system.core.common.constant.factory.ConstantFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author yangcheng
* @version PlanEditUnitTest.java, v0.12019-06-1016:26 yangchengExp$
*/
public class PlanEditUnitTest extends BaseAutoTests {
@Autowired
private PlanService planService;
@Autowired
private AcctDateDAO acctDateDAO;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private ChangeManager changeManager;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanFundHandler planFundHandler;
@Autowired
private PlanAllocRepo planAllocRepo;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@XTest(relatePath = "unittest/plan/planTest")
@Test(dataProvider = "YamlDataProvider", description = "计划新增")
public void create(ICase iCase, String acctDate, PlanOprParam param, List<LinkedHashMap> allocCheckList, List<LinkedHashMap> itemCheckList) {
ConstantFactory.me().securityLogin("administrator");
// 更新会计日期
try {
super.updateDate(acctDate, OrgCodeEnum.ABS.getCode());
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
planService.edit(param);
BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(param.getPlanNo(), "PENDING");
if (bizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult result = new ProcessAfterResult();
result.setBusinessKey(bizData.getChangeNo());
result.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(result);
// 执行余额查询
PlanBase planEntity = planRepo.getPlanByNo(param.getPlanNo());
planFundHandler.executeQueryBalance(planEntity, trfDate);
List<PlanAlloc> planAllocs = planAllocRepo.queryByPlanNo(param.getPlanNo());
List<Date> clearDatelist = planAllocs.stream().map(PlanAlloc::getClearDate).collect(Collectors.toList());
List<Date> checkDatelist = allocCheckList.stream().map(item -> {
return DateUtil.parse((String) item.get("payDate"));
}).collect(Collectors.toList());
// 校验分配计划
VarChecker.checkEquals(clearDatelist, checkDatelist);
// 校验分配计划数量
planAllocs.sort(Comparator.comparing(PlanAlloc::getClearDate));
List<Integer> allocItemList = planAllocs.stream().map(item -> {
return item.getPlanAllocItemList().size();
}).collect(Collectors.toList());
List<Integer> allocItemCheckList = itemCheckList.stream().map(item -> {
return (Integer) item.get("cnt");
}).collect(Collectors.toList());
VarChecker.checkEquals(allocItemList, allocItemCheckList);
}
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package com.abssqr.plat.test.unittest.planAlloc;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanDailyJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocDetailQryParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocPayParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocQryParam;
import com.abssqr.plat.common.facade.result.plan.PlanAllocPayInfoVO;
import com.abssqr.plat.common.facade.result.plan.PlanAllocVO;
import com.abssqr.plat.common.facade.service.plan.PlanAllocPayService;
import com.abssqr.plat.common.facade.service.plan.PlanAllocService;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.List;
import static org.unitils.reflectionassert.ReflectionAssert.assertReflectionEquals;
/**
* 分配兑付测试
* @author hanfei
* @version PlanAllocUnitTest.java, v0.1 2020-01-09 20:21 hanfei
*/
//@ActiveProfiles("dep")
public class PlanAllocUnitTest extends BaseAutoTests {
@Autowired
private PlanAllocService planAllocService;
@Autowired
private PlanAllocPayService planAllocPayService;
@Autowired
private PlanDailyJob planDailyJob;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private ChangeManager changeManager;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@XTest(relatePath = "unittest/PlanAlloc/query")
@Test(dataProvider = "YamlDataProvider", description = "查询分配计划")
public void getPlanAllocTest(ICase iCase, PlanAllocQryParam param){
try{
planAllocService.getPlanAlloc(param);
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
/**
* 1、新增分配计划
* 2、保存分配计划
* 3、提交分配计划、并审批通过、并每日任务冻结
*/
// @XTest(relatePath = "unittest/PlanAlloc/init")
// @Test(dataProvider = "YamlDataProvider", description = "初始化分配计划,日初冻结")
// public void initPlanAllocFrozenTest(ICase iCase, String strDate, PlanAllocEditParam param, String planType,
// boolean submit, boolean approve, boolean dailyJob){
// try{
// PlanTypeEnum typeEnum = PlanTypeEnum.getByCode(planType);
// PlanAllocVO allocVO = planAllocService.edit(param, typeEnum, submit);
//
// // 审批
// if (approve){
// ConstantFactory.me().securityLogin("administrator");
// BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(allocVO.getAllocNo(), "PENDING");
// if (bizData != null) {
// // 审批通过
// ProcessAfterResult result = new ProcessAfterResult();
// result.setBusinessKey(bizData.getChangeNo());
// result.setStatusEnum(ApproveStatusEnum.PASSED);
// changeManager.handle(result);
// }
// }
// // 每日任务
// if (dailyJob){
// super.updateDate(strDate);
// planDailyJob.doExecute();
// }
// } finally {
// // 校验数据
// super.checkDB(iCase);
// super.clearDB(iCase);
// }
// }
@XTest(relatePath = "unittest/PlanAlloc/info")
@Test(dataProvider = "YamlDataProvider", description = "确认分配详情")
public void detailPlanAlloc(ICase iCase, PlanAllocPayParam param, PlanAllocPayInfoVO infoVOCheck){
try{
PlanAllocPayInfoVO infoVO = planAllocPayService.allocInfo(param);
// 校验数据
assertReflectionEquals(infoVO, infoVOCheck);
} finally {
super.clearDB(iCase);
}
}
/**
* 1、放款池线上分配
* 2、放款池线下分配
* 3、承接池线上分配
* 4、承接池线下分配
*/
@XTest(relatePath = "unittest/PlanAlloc/pay")
@Test(dataProvider = "YamlDataProvider", description = "分配计划分配")
public void payPlanAllocTest(ICase iCase, String strDate, PlanAllocPayParam param, Boolean pay){
try{
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
planAllocPayService.allocPay(param);
if (pay) {
PlanAllocDetailQryParam qryParam = new PlanAllocDetailQryParam();
qryParam.setAllocNo(param.getAllocNo());
PlanAllocVO vo = planAllocService.getPlanAllocDetail(qryParam);
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(vo.getPlanNo());
super.capitalOrderMock(capitalOrders);
}
} finally {
// 校验数据
super.checkDB(iCase);
super.clearDB(iCase);
}
}
}
package com.abssqr.plat.test.unittest.report;
import java.util.Date;
import java.util.List;
import java.util.Map;
import cn.hutool.core.date.DateUtil;
import com.abssqr.plat.biz.shared.dispatcher.TaskGroupService;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherStarter;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.transfer.AstTrTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherSplitor;
import com.abssqr.plat.biz.shared.dispatcher.wkAstSync.mfs.WkMfsAstSyncDispatcherStarter;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskExecutor;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskLoader;
import com.abssqr.plat.biz.shared.dispatcher.wkPlanReport.PlanReportTaskStarter;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingOrderHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstClearingStatHandler;
import com.abssqr.plat.biz.shared.handler.PlanAstStatTaskHandler;
import com.abssqr.plat.biz.shared.handler.PlanFundHandler;
import com.abssqr.plat.biz.shared.handler.WkPlanReportHandler;
import com.abssqr.plat.biz.shared.scheduler.job.ast.ZLFinSerFeeJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanCapitalOrderJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanDailyJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanPackJob;
import com.abssqr.plat.common.dal.mysql.auto.dao.BizDataChangeDAO;
import com.abssqr.plat.common.dal.mysql.auto.dataobject.BizDataChangeDO;
import com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum;
import com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum;
import com.abssqr.plat.common.facade.enums.PlanStatusEnum;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.plan.PlanCapitalOrder;
import com.abssqr.plat.common.facade.param.analyse.AnalyseBaseParam;
import com.abssqr.plat.common.facade.param.analyse.AnalyseTrendChartParam;
import com.abssqr.plat.common.facade.param.analyse.CalcFundParam;
import com.abssqr.plat.common.facade.param.plan.PlanOprParam;
import com.abssqr.plat.common.facade.param.plan.PlanPageQryParam;
import com.abssqr.plat.common.facade.param.plan.alloc.PlanAllocQryParam;
import com.abssqr.plat.common.facade.result.BasePage;
import com.abssqr.plat.common.facade.result.analyse.AnalyseChartResultVO;
import com.abssqr.plat.common.facade.result.analyse.AnalyseDayAmtInfoVO;
import com.abssqr.plat.common.facade.result.analyse.AnalyseDayAstInfoVO;
import com.abssqr.plat.common.facade.result.analyse.CalcFundDefaultParam;
import com.abssqr.plat.common.facade.result.analyse.CalcFundResultVO;
import com.abssqr.plat.common.facade.result.analyse.FormationAstItemVO;
import com.abssqr.plat.common.facade.result.analyse.PlanAnalyseVO;
import com.abssqr.plat.common.facade.service.analyse.AnalyseFundSpvService;
import com.abssqr.plat.common.facade.service.analyse.AnalyseInfoChartService;
import com.abssqr.plat.common.facade.service.plan.PlanAllocService;
import com.abssqr.plat.common.facade.service.plan.PlanService;
import com.abssqr.plat.common.model.domain.plan.PlanAstStatTask;
import com.abssqr.plat.common.model.domain.task.CommonTask;
import com.abssqr.plat.common.model.domain.task.TrTask;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.ast.PlanAstStatTaskRepo;
import com.abssqr.plat.common.model.repo.plan.PlanCapitalOrderRepo;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.model.wk.domain.sync.WkMfsSyncCtr;
import com.abssqr.plat.common.model.wk.repo.WkMfsSyncCtrRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.change.ChangeManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.bpm.domain.result.ProcessAfterResult;
import com.general.system.bpm.enums.ApproveStatusEnum;
import com.general.system.common.util.DateTimeUtil;
import com.general.system.common.util.LogUtil;
import com.general.system.core.common.constant.factory.ConstantFactory;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
/**
* 报表及项目分析页面统计
*/
//@ActiveProfiles("dev")
public class PlanReportChartTest extends BaseAutoTests {
@Autowired
private PlanService planService;
@Autowired
private PlanAstStatTaskHandler planAstStatTaskHandler;
@Autowired
private PlanDailyJob planDailyJob;
@Autowired
private ChangeManager changeManager;
@Autowired
private AstTrTaskLoader astTrTaskLoader;
@Autowired
private PlanFundHandler planFundHandler;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanAllocService planAllocService;
@Autowired
private AstTrTaskExecutor astTrTaskExecutor;
@Autowired
private PlanAstStatTaskRepo planAstStatTask;
@Autowired
private PlanAstClearingStatHandler planAstStatHandler;
@Autowired
private WkMfsAstSyncDispatcherLoader wkMfsAstSyncDispatcherLoader;
@Autowired
private WkMfsAstSyncDispatcherSplitor wkMfsAstSyncDispatcherSplitor;
@Autowired
private WkMfsAstSyncDispatcherExecutor wkMfsAstSyncDispatcherExecutor;
@Autowired
private WkMfsAstSyncDispatcherStarter wkMfsAstSyncDispatcherStarter;
@Autowired
private WkMfsSyncCtrRepo wkMfsSyncCtrRepo;
@Autowired
private BizDataChangeDAO bizDataChangeDAO;
@Autowired
private ZLFinSerFeeJob zlFinSerFeeJob;
@Autowired
private PlanAstClearingOrderHandler planAstClearingOrderHandler;
@Autowired
private PlanCapitalOrderRepo planCapitalOrderRepo;
@Autowired
private PlanPackJob planPackJob;
@Autowired
private PlanReportTaskStarter planReportTaskStarter;
@Autowired
private PlanReportTaskLoader planReportTaskLoader;
@Autowired
private PlanReportTaskExecutor planReportTaskExecutor;
@Autowired
private PlanAstMatchDispatcherLoader planAstMatchLoader;
@Autowired
private PlanAstMatchDispatcherExecutor planAstMatchExecutor;
@Autowired
private PlanAstMatchDispatcherStarter planAstMatchDispatcherStarter;
@Autowired
private PlanReportRepo planReportRepo;
@Autowired
private PlanCapitalOrderJob planCapitalOrderJob;
@Autowired
private WkPlanReportHandler wkPlanReportHandler;
@Autowired
private OrgAcctDayComponent orgAcctDayComponent;
@XTest(relatePath = "unittest/planReport/chart")
@Test(dataProvider = "YamlDataProvider", description = "创建并生效计划", priority = 1)
public void createPlanTestChart(ICase iCase, String acctDate, PlanOprParam planParam) {
ConstantFactory.me().securityLogin("administrator");
// 更新会计日期
try {
Date strDate = DateUtil.parseDate(acctDate);
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
// 计划管理-->提交审批
LogUtil.info(logger, " ---- 1 计划初始化");
planService.edit(planParam);
BizDataChangeDO bizData = bizDataChangeDAO.getByBizNoAndStatus(planParam.getPlanNo(), "PENDING");
if (bizData != null) {
// 审批-->创建水位与科目
ProcessAfterResult result = new ProcessAfterResult();
result.setBusinessKey(bizData.getChangeNo());
result.setStatusEnum(ApproveStatusEnum.PASSED);
changeManager.handle(result);
}
// 计划日切更新状态
super.updateDate(DateTimeUtil.addDays(strDate, 1), OrgCodeEnum.ABS.getCode());
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
PlanBase planEntity = planRepo.getPlanByNo(planParam.getPlanNo());
//执行计划每日任务
planDailyJob.lockEntityAndExecute(trfDate.getStandardDate(), planEntity);
// 执行余额查询
LogUtil.info(logger, " ---- 2 执行余额查询");
planFundHandler.executeQueryBalance(planEntity, new Day(strDate));
// 生成默认分配计划
LogUtil.info(logger, " ---- 3 生成默认分配计划");
PlanAllocQryParam allocParm = new PlanAllocQryParam();
allocParm.setPlanNo(planParam.getPlanNo());
planAllocService.getPlanAlloc(allocParm);
} finally {
// 校验数据
checkDB(iCase);
}
}
/**
* 进行同步数据处理 testOnly 按顺序执行用例文件
* @param iCase
* @param acctDate
* @param planNo
* @param spvNo
* @param orgCode
*/
@XTest(relatePath = "dal/wkdata",
testOnly = { "initWKData_chart_20190703", "initWKData_chart_20190704", "initWKData_chart_20190705" })
@Test(dataProvider = "YamlDataProvider", description = "同步五矿数据-初始化", priority = 2)
public void dailyJobChart(ICase iCase, String acctDate, String planNo, String spvNo, String orgCode) {
try {
// 创建分区
autoPartition(OrgCodeEnum.getByCode(orgCode).getCode());
// 更新会计日期
Day strDate = new Day(acctDate);
super.updateDate(strDate.getTomorrow().getStandardDate(), OrgCodeEnum.ABS.getCode());
// 对应机构日
super.updateDate(strDate.getStandardDate(), orgCode);
// // 会计日切换
// orgAcctDayComponent.acctDaySwitch();
// 执行业务
PlanBase plan = planRepo.getPlanByNo(planNo);
PlanBase spv = planRepo.getPlanByNo(spvNo);
// 整体流程
this.execute(plan, spv, orgCode);
} finally {
checkDB(iCase);
// super.clearDB(iCase);
}
}
/**
* 机构编码
*/
private void execute(PlanBase plan, PlanBase spv, String orgCode) {
String planNo = plan.getPlanNo();
String spvNo = spv.getPlanNo();
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
LogUtil.info(logger, " ---- 2 计划每日任务");
planDailyJob.lockEntityAndExecute(trfDate.getStandardDate(), plan);
planDailyJob.lockEntityAndExecute(trfDate.getStandardDate(), spv);
LogUtil.info(logger, " ---- 3 五矿数据模型转换");
List<WkMfsSyncCtr> syncNodes = wkMfsAstSyncDispatcherLoader.loadToDoNodes(
new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList(1L, 9999999L);
}
@Override
public void finish() {
}
}
, new TaskGroupService() {
@Override
public List getTasks() {
return Lists.newArrayList();
}
@Override
public void finish() {
}
}
, 20);
for (WkMfsSyncCtr syncNode : syncNodes) {
if (ToolUtil.equals(syncNode.getOrgNo(), orgCode)){
wkMfsAstSyncDispatcherExecutor.doExecute(syncNode);
}
}
// wk1009AstSyncDispatcherSplitor.setOrgCode(orgCode);
//所有同步数据处理完成后,更新任务为成功
LogUtil.info(logger, " ---- 更新任务");
wkMfsAstSyncDispatcherSplitor.split();
// 筛选资产包创建
LogUtil.info(logger, " ---- 4 筛选资产包创建");
planPackJob.doExecute();
LogUtil.info(logger, " ---- 5 资产筛选");
List<CommonTask> commonTask = planAstMatchLoader.loadToDoNodes(10);
for (CommonTask task : commonTask) {
if (task.getTaskType().equals(CommonTaskTypeEnum.PACK_MATCH)) {
planAstMatchExecutor.doExecute(task);
}
}
LogUtil.info(logger, " ---- 6 资产转让");
List<TrTask> trTasks = astTrTaskLoader.loadToDoNodes(10);
for (TrTask trTask : trTasks) {
astTrTaskExecutor.doExecute(trTask);
}
LogUtil.info(logger, " ---- 10 金融服务费定时任务统计");
zlFinSerFeeJob.setZlOrgCode(orgCode);
zlFinSerFeeJob.doExecute();
LogUtil.info(logger, " ---- 7 清算汇总");
planAstStatTaskHandler.handle(planNo, trfDate);
planAstStatTaskHandler.handle(spvNo, trfDate);
String execTms = "999912312359";
PlanAstStatTask astStatTask1 = planAstStatTask.getPlanNo(planNo);
if (astStatTask1 != null) {
astStatTask1.setStatus(OrgAstStatStatusEnum.PROCESS);
astStatTask1.setMinId(null);
planAstStatTask.updateTask(astStatTask1);
planAstStatHandler.execute(astStatTask1, execTms);
}
PlanAstStatTask astStatTask2 = planAstStatTask.getPlanNo(spvNo);
if (astStatTask2 != null) {
astStatTask2.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask2);
planAstStatHandler.execute(astStatTask2, execTms);
astStatTask2.setAccountDate(trfDate.getStandardDate());
astStatTask2.setMinId(null);
astStatTask2.setStatus(OrgAstStatStatusEnum.PROCESS);
planAstStatTask.updateTask(astStatTask2);
planAstStatHandler.execute(astStatTask2, execTms);
}
// 结算任务处理
LogUtil.info(logger, " ---- 8 结算处理");
planAstClearingOrderHandler.handle(plan);
planAstClearingOrderHandler.handle(spv);
// wk交易调用
// 资金订单状态由wait-->succ, 记得修改next_exec_time <= sysdate
LogUtil.info(logger, " ---- 9 支付处理");
super.validJobCtr(planCapitalOrderJob.getJobName());
List<PlanCapitalOrder> capitalOrders = planCapitalOrderRepo.getInitListByPlanNo(planNo);
capitalOrders.addAll(planCapitalOrderRepo.getInitListByPlanNo(spvNo));
super.capitalOrderMock(capitalOrders);
// 放款池可能会有回转放的结算单需要执行
planAstClearingOrderHandler.handle(spv);
List<PlanCapitalOrder> spvReturn = planCapitalOrderRepo.getInitListByPlanNo(spv.getPlanNo());
super.capitalOrderMock(spvReturn);
super.invalidJobCtr(planCapitalOrderJob.getJobName());
// 放款池的Item_default 初始化
planReportRepo.defaultRPT001Init(spv.getPlanNo(), spv.getBeginDate());
LogUtil.info(logger, " ---- 11 计划报表");
List<CommonTask> tasks = planReportTaskLoader.loadToDoNodes(20);
while (tasks.size() > 0){
for(CommonTask task: tasks){
if(ToolUtil.equals(task.getContext(), planNo))
planReportTaskExecutor.doExecute(task);
}
for(CommonTask task: tasks){
if(ToolUtil.equals(task.getContext(), spvNo))
planReportTaskExecutor.doExecute(task);
}
tasks = planReportTaskLoader.loadToDoNodes(20);
}
}
@Autowired
private AnalyseInfoChartService analyseInfoChartService;
@XTest(relatePath = "unittest/planReport/overview")
@Test(dataProvider = "YamlDataProvider", description = "资金分析", priority = 3)
public void overviewAmtTest(ICase iCase, AnalyseBaseParam param) {
try {
AnalyseDayAmtInfoVO result = analyseInfoChartService.getDayAmtInfo(param);
Assert.assertNotNull(result);
} finally {
}
}
@XTest(relatePath = "unittest/planReport/overview")
@Test(dataProvider = "YamlDataProvider", description = "资产分析", priority = 3)
public void overviewAstTest(ICase iCase, AnalyseBaseParam param) {
try {
AnalyseDayAstInfoVO result = analyseInfoChartService.getDayAstInfo(param);
Assert.assertNotNull(result);
} finally {
}
}
@XTest(relatePath = "unittest/planReport/overview")
@Test(dataProvider = "YamlDataProvider", description = "资产分期结构", priority = 3)
public void formationAstTest(ICase iCase, AnalyseBaseParam param) {
try {
Map<String, List<FormationAstItemVO>> result = analyseInfoChartService.getFormationAst(param);
Assert.assertNotNull(result);
} finally {
checkDB(iCase);
}
}
@XTest(relatePath = "unittest/planReport/analyse")
@Test(dataProvider = "YamlDataProvider", description = "统计图数据", priority = 3)
public void chartNodeTest(ICase iCase, AnalyseTrendChartParam param) {
try {
AnalyseChartResultVO resultVO = analyseInfoChartService.trendChartService(param);
Assert.assertNotNull(resultVO);
} finally {
}
}
@Autowired
private AnalyseFundSpvService analyseFundSpvService;
@XTest(relatePath = "unittest/planReport/overview")
@Test(dataProvider = "YamlDataProvider", description = "查询计划概要信息", priority = 3)
public void testAnalyseSpvPlan(ICase iCase, AnalyseBaseParam param) {
try {
PlanAnalyseVO result = analyseFundSpvService.getAnalyseSpvPlan(param);
Assert.assertNotNull(result);
} finally {
}
}
@XTest(relatePath = "unittest/planReport/overview")
@Test(dataProvider = "YamlDataProvider", description = "获取短期资金需求计算器默认显示数据", priority = 3)
public void testFundCalcView(ICase iCase, AnalyseBaseParam param) {
try {
CalcFundDefaultParam result = analyseFundSpvService.fundCalcView(param);
Assert.assertNotNull(result);
} finally {
}
}
@XTest(relatePath = "unittest/planReport/calc")
@Test(dataProvider = "YamlDataProvider", description = "短期资金需求计算器", priority = 4)
public void testFundCalcView(ICase iCase, CalcFundParam param) {
try {
CalcFundResultVO result = analyseFundSpvService.fundCalc(param);
Assert.assertNotNull(result);
} finally {
}
}
@XTest(relatePath = "unittest/planReport/page")
@Test(dataProvider = "YamlDataProvider", description = "查询项目计划分析列表", priority = 4)
public void testQueryAnalyseSpvPlan(ICase iCase, PlanPageQryParam param) {
try {
ConstantFactory.me().securityLogin("administrator");
BasePage result = analyseFundSpvService.queryAnalyseSpvPlan(param);
Assert.assertNotNull(result);
} finally {
}
}
@XTest(relatePath = "unittest/planReport/month" )
@Test(dataProvider = "YamlDataProvider", description = "测试项目管理报表", priority = 5)
public void MonthReport(ICase iCase, String acctDate, String spvPlanNo, String planNo) {
try {
Date strDate = DateUtil.parse(acctDate);
super.updateDate(strDate, OrgCodeEnum.ABS.getCode());
List<PlanBase> onGoingPlans = planRepo.getPlansByStatus(null, PlanStatusEnum.ONGOING);
for (PlanBase planBase : onGoingPlans) {
if (ToolUtil.equals(planBase.getPlanNo(), spvPlanNo)
|| ToolUtil.equals(planBase.getPlanNo(), planNo)) {
wkPlanReportHandler.checkAndBuildMonthPlanReport(strDate, planBase);
}
}
} finally {
checkDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.report;
import cn.hutool.core.date.DateUtil;
import com.abssqr.plat.biz.shared.handler.WkPlanReportHandler;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
import java.util.Date;
/**
* 报表默认数据测试
* @author hanfei
* @version $Id: PlanReportDefaultTest.java, v 0.1 2019-12-25 2:25 PM hanfei Exp $
*/
public class PlanReportDefaultTest extends BaseAutoTests {
@Autowired
private WkPlanReportHandler wkPlanReportHandler;
@Autowired
private PlanReportRepo planReportRepo;
@Autowired
private PlanManager planManager;
@XTest(relatePath = "unittest/planReport/default")
@Test(dataProvider = "YamlDataProvider", description = "生成默认item", priority = 1)
public void defaultRPT001InitTest(ICase iCase, String acctDate, String planNo) {
try {
Date accountDate = DateUtil.parse(acctDate);
PlanBase planBase = planManager.getPlanFullByNo(planNo);
planReportRepo.defaultRPT001Init(planBase.getPlanNo(), accountDate);
} finally {
super.checkDB(iCase);
//super.clearDB(iCase);
}
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.wk;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import org.testng.annotations.Test;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.test.unittest.wk: WkPayCallBackTest.java, v 0.1 2019-06-21 18:25 bangis.wangdf Exp $
*/
public class WkPayCallBackTest {
@Test
public void testCall() {
String xxx = null;
try {
xxx = callXW("z水电费水电费是", "http://localhost:8007/wkplat/callback/wkpay/trade");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(xxx);
}
/**
* 回调小微
*
* @param msg 回调参数
* @param url 回调小微地址
* @return
* @throws Exception
*/
public static String callXW(String msg, String url) throws Exception {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
//conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
//
conn.setConnectTimeout(1000);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "GBK"));
// 发送请求参数
String messge = "msg=" + URLEncoder.encode(msg, "GBK");
out.print(messge);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
}
// 使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
public static void main(String[] args) throws UnsupportedEncodingException {
String testGBK = new String("z水电费水电费是".getBytes());
String encodeGBK = URLEncoder.encode(testGBK, "GBK");
String decodeUtf8 = URLDecoder.decode(encodeGBK, "UTF-8");
String d0 = URLEncoder.encode(decodeUtf8, "GBK");
String d1 = URLEncoder.encode(decodeUtf8, "UTF-8");
String d2 = URLDecoder.decode(d1, "UTF-8");
String testUtf8 = new String(decodeUtf8.getBytes("UTF-8"), "GBK");
String t1 = new String(testUtf8.getBytes("GBK"), "UTF-8");
return;
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.wk;
import com.abssqr.plat.common.integration.wk.WkPayIntegration;
import com.abssqr.plat.test.BaseAutoTests;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.test.unittest.wk: WkPayIntegrationTest.java, v 0.1 2019-06-19 11:44 bangis.wangdf Exp $
*/
public class WkPayIntegrationTest extends BaseAutoTests {
@Autowired
private WkPayIntegration wkPayIntegration;
// @XTest(relatePath = "unittest/wk/pay/time")
// @Test(dataProvider = "YamlDataProvider", description = "time")
// public void testDate(ICase iCase, Date time){
// System.out.println(DateTimeUtil.formatYMDHMSSLong(time));
// }
//
// @XTest(relatePath = "unittest/wk/pay/account")
// @Test(dataProvider = "YamlDataProvider", description = "账户信息维护")
// public void testAccount(ICase iCase, ListObject listObject) {
//
// Result<OprRstHeader, AccountListResult> account = wkPayIntegration.account(SequenceUtil.genWkSeqNo(),
// listObject.getList());
// VarChecker.checkEquals(account.getBody().getAccountList().get(0).getStatus(), WkAcctStatusEnum.成功);
//
// }
//
// @XTest(relatePath = "unittest/wk/pay/balance")
// @Test(dataProvider = "YamlDataProvider", description = "账户余额")
// public void testBalance(ICase iCase, ListObject listObject) {
//
// Result<QryRstHeader, BalanceResult> balance = wkPayIntegration.balance(SequenceUtil.genWkSeqNo(),
// (String)listObject.getList().get(0), WkChannelNoEnum.BC_YQ0001);
// VarChecker.checkNotNull(balance);
// }
//
// @XTest(relatePath = "unittest/wk/pay/trade")
// @Test(dataProvider = "YamlDataProvider", description = "代理交易")
// public void testTrade(ICase iCase, TradeList tradeList) {
//
// Result<OprRstHeader, WkBody> trade = wkPayIntegration.trade(SequenceUtil.genWkSeqNo(), tradeList);
//
// VarChecker.checkNotNull(trade);
//
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// List<String> tradeNos = tradeList.getTradeList().stream().map(TradeInfo :: getTradeNo).collect(Collectors.toList());
// Result<QryRstHeader, TradeResult> result = wkPayIntegration.tradeRstQry(
// SequenceUtil.genWkSeqNo(), tradeNos);
// VarChecker.checkNotNull(result);
// }
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.test.unittest.wk;
import cn.hutool.core.collection.CollectionUtil;
import com.abssqr.plat.common.facade.enums.AccountAttributeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.integration.wk.domain.opr.request.acct.WkAccount;
import com.abssqr.plat.common.integration.wk.domain.qry.response.trade.TradeResult;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.util.base.autoconfig.AbsConfig;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.abssqr.plat.test.BaseAutoTests;
import com.abssqr.plat.test.BaseAutoWithOutMockTests;
import com.abssqr.test.annotation.XTest;
import com.abssqr.test.icase.ICase;
import com.general.system.common.model.Money;
import com.general.system.common.model.exception.BaseCommonException;
import com.general.system.common.util.LogUtil;
import com.general.system.common.util.VarChecker;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;
/**
* 五矿接口测试
* @author hanfei
* @version $Id: WkPayManagerTest.java, v 0.1 2019-06-27 2:35 PM hanfei Exp $
*/
public class WkPayManagerTest extends BaseAutoWithOutMockTests {
@Autowired
private WkPayManager wkPayManager;
public final static String testBag = "manager/pay";
@Autowired
AbsConfig absConfig;
/**
* 租户签约与维护
*
* @return
*/
@XTest(relatePath = testBag + "/project")
@Test(dataProvider = "YamlDataProvider", description = "租户签约与维护")
public void project(ICase iCase) {
boolean b = wkPayManager.project();
VarChecker.checkEquals(b, true, "租户签约与维护-异常");
}
/**
* 账户信息维护
*
* 账户 1 :账号 755915676910701 账户名称: 企业网银新20161058 开户分行:招商银行深圳分行
* 账户 2 :账号 755915676910806 账户名称: 企业网银新20161058 开户分行:招商银行深圳分行
*
* 账户 3 :账号 755915712310502 账户名称: 企业网银新20161397 开户分行:招商银行深圳分行
* 账户 4 :账号 755915712310607 账户名称: 企业网银新20161397 开户分行:招商银行深圳分行
* 000004_001_P190625 === 755915676910701
* 000004_001_P830330 === 755915676910806
*
*
* @param planNo
* @param planName
* @return
*/
@XTest(relatePath = testBag + "/account")
@Test(dataProvider = "YamlDataProvider", description = "账户信息维护")
public void account(ICase iCase, String planNo, String planName) {
WkAccount account = wkPayManager.createAccount(planNo, planName, AccountAttributeEnum.NORMAL);
LogUtil.info(logger, account.toString());
VarChecker.checkNotNull(account, "账户信息维护-异常");
}
/**
* 账户余额查询 B100002
* 最多50条
*
* @param accountNo
* @return
*/
@XTest(relatePath = testBag + "/balance")
@Test(dataProvider = "YamlDataProvider", description = "账户余额查询")
public void balance(ICase iCase, String accountNo) {
try {
Money amt = wkPayManager.balance(accountNo, WkChannelNoEnum.BC_YQ0001);
}catch (BaseCommonException e){
e.printStackTrace();
}
checkDB(iCase);
}
/**
* 代理交易
*
* @return
*/
@XTest(relatePath = testBag + "/trade")
@Test(dataProvider = "YamlDataProvider", description = "代理交易")
public void trade(ICase iCase, Long money, Account sourceAcct, Account targetAcct) {
String enNo = wkPayManager.trade(sourceAcct, targetAcct, Money.createWithCent(money),"钉钉");
LogUtil.info(logger, enNo);
// 休息一下
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 代理交易结果查询
TradeResult tradeResult = wkPayManager.tradeRstQry(CollectionUtil.newArrayList(enNo));
LogUtil.info(logger, tradeResult.toString());
}
/**
* 代理交易
*
* @return
*/
@XTest(relatePath = testBag + "/trade")
@Test(dataProvider = "YamlDataProvider", description = "代理交易")
public void trade2(ICase iCase, Long money, Account sourceAcct, Account targetAcct) {
String enNo = wkPayManager.trade(sourceAcct, targetAcct, Money.createWithCent(money),null);
LogUtil.info(logger, enNo);
}
/**
* 代理交易结果查询
*
* @param tradeNo
* @return
*/
@XTest(relatePath = testBag + "/tradeRstQry")
@Test(dataProvider = "YamlDataProvider", description = "代理交易结果查询")
public void tradeRstQry(ICase iCase, String tradeNo) {
TradeResult tradeResult = wkPayManager.tradeRstQry(CollectionUtil.newArrayList(tradeNo+1));
LogUtil.info(logger, tradeResult.toString());
}
}
......@@ -4,8 +4,12 @@
*/
package com.abssqr.plat.web.config;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import cn.hutool.core.util.StrUtil;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.general.system.common.model.IEnum;
import com.general.system.common.util.LogUtil;
import com.general.system.modular.result.DictResult;
......@@ -15,11 +19,6 @@ import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* 字典配置实现
* @author hanfei
......@@ -39,7 +38,7 @@ public class DictConfigRealize extends DictStaticConfig {
public Map<String, IEnum[]> getDictEnum() {
Map<String, IEnum[]> dictMap = new HashMap<>();
// 渠道编号
dictMap.put("channelNo", WkChannelNoEnum.values());
//dictMap.put("channelNo", WkChannelNoEnum.values());
return dictMap;
}
......
......@@ -8,53 +8,36 @@ package com.abssqr.plat.web.controller.job;
//import com.abssqr.plat.biz.shared.scheduler.job.plan.LenderOrgAstClearingOrderJob;
//import com.abssqr.plat.biz.shared.scheduler.job.plan.LenderOrgAstStatJob;
import cn.hutool.core.date.DateUtil;
import com.abssqr.plat.biz.shared.handler.WkPlanReportHandler;
import java.util.List;
import com.abssqr.plat.biz.shared.scheduler.job.ast.ZLFinSerFeeJob;
import com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob;
import com.abssqr.plat.biz.shared.scheduler.job.keeper.node.WkDataCheckKeeper;
import com.abssqr.plat.biz.shared.scheduler.job.plan.LenderOrgCapitalJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanAstClearingOrderJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanAstStatJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanCapitalOrderJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanCapitalOrderResJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanDailyJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanFundJob;
import com.abssqr.plat.biz.shared.scheduler.job.plan.PlanPackJob;
import com.abssqr.plat.biz.shared.scheduler.job.sync.ast.ZLOriginalAstSyncJob;
import com.abssqr.plat.common.facade.enums.PlanTypeEnum;
import com.abssqr.plat.common.facade.enums.ReportTypeEnum;
import com.abssqr.plat.common.facade.model.account.Account;
import com.abssqr.plat.common.facade.model.plan.PlanBase;
import com.abssqr.plat.common.facade.model.report.DailyReportDateField;
import com.abssqr.plat.common.facade.model.report.PlanReport;
import com.abssqr.plat.common.facade.service.AccountService;
import com.abssqr.plat.common.integration.wk.enums.WkChannelNoEnum;
import com.abssqr.plat.common.model.domain.task.ctr.AstSyncTaskCtr;
import com.abssqr.plat.common.model.enums.OrgCodeEnum;
import com.abssqr.plat.common.model.repo.plan.PlanRepo;
import com.abssqr.plat.common.model.repo.report.PlanReportRepo;
import com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo;
import com.abssqr.plat.common.util.base.Day;
import com.abssqr.plat.common.util.utils.DayUtil;
import com.abssqr.plat.core.service.accounting.OrgAcctDayComponent;
import com.abssqr.plat.core.service.plan.PlanManager;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import cn.hutool.core.date.DateUtil;
import com.general.enhanced.controller.annotation.RestJsonController;
import com.general.system.common.model.BaseResult;
import com.general.system.common.model.Money;
import com.general.system.common.util.VarChecker;
import com.general.system.tool.util.ToolUtil;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.MutablePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* job 手工出发
*
......@@ -69,30 +52,14 @@ public class JobController {
@Autowired
private ZLOriginalAstSyncJob zlOriginalAstSyncJob;
@Autowired
private WkPlanReportHandler wkPlanReportHandler;
@Autowired
private PlanManager planManager;
@Autowired
private PlanRepo planRepo;
@Autowired
private PlanAstClearingOrderJob planAstClearingOrderJob;
@Autowired
private LenderOrgCapitalJob lenderOrgCapitalJob;
@Autowired
private PlanAstStatJob planAstStatJob;
@Autowired
private PlanCapitalOrderJob planCapitalOrderJob;
@Autowired
private PlanCapitalOrderResJob planCapitalOrderResJob;
@Autowired
private PlanDailyJob planDailyJob;
@Autowired
private PlanFundJob planFundJob;
@Autowired
private PlanPackJob planPackJob;
@Autowired
private WkPayManager wkPayManager;
@Autowired
private ZLFinSerFeeJob zlFinSerFeeJob;
@Autowired
private PlanReportRepo planReportRepo;
......@@ -147,17 +114,7 @@ public class JobController {
return BaseResult.success(null);
}
/**
* 资金到账情况查询
*
* @return
* @description
*/
@RequestMapping(path = "/job/planFundJob.json", method = RequestMethod.GET)
public BaseResult<Boolean> planFundJob() {
planFundJob.doExecute();
return BaseResult.success(null);
}
/**
* 招联资产数据同步
......@@ -177,85 +134,7 @@ public class JobController {
return BaseResult.success(null);
}
/**
* 手动触发交易支付单
*
* @return
* @description
*/
@RequestMapping(path = "/job/planCapitalOrderJob.json", method = RequestMethod.GET)
public BaseResult<Boolean> planCapitalOrderJob() {
planCapitalOrderJob.doExecute();
return BaseResult.success(null);
}
/**
* 交易支付单查询结果
*
* @return
* @description
*/
@RequestMapping(path = "/job/planCapitalOrderResJob.json", method = RequestMethod.GET)
public BaseResult<Boolean> planCapitalOrderResJob() {
planCapitalOrderResJob.doExecute();
return BaseResult.success(null);
}
// /**
// * @return
// * @description
// */
// @RequestMapping(path = "/job/lenderOrgAstClearingOrderJob.json", method = RequestMethod.GET)
// public BaseResult<Boolean> lenderOrgAstClearingOrderJob() {
// lenderOrgAstClearingOrderJob.doExecute();
// return BaseResult.success(null);
// }
//
// /**
// * @return
// * @description
// */
// @RequestMapping(path = "/job/lenderOrgAstStatJob.json", method = RequestMethod.GET)
// public BaseResult<Boolean> lenderOrgAstStatJob() {
// lenderOrgAstStatJob.doExecute();
// return BaseResult.success(null);
// }
/**
* 结算单
*
* @return
* @description
*/
@RequestMapping(path = "/job/planAstClearingOrderJob.json", method = RequestMethod.GET)
public BaseResult<Boolean> planAstClearingOrderJob() {
planAstClearingOrderJob.doExecute();
return BaseResult.success(null);
}
/**
* 资产筛选
*
* @return
* @description
*/
// @RequestMapping(path = "/job/planAstMatchJob.json", method = RequestMethod.GET)
// public BaseResult<Boolean> planAstMatchJob() {
// planAstMatchJob.doExecute();
// return BaseResult.success(null);
// }
/**
* 资产清算统计业务 初始化清算汇总调度任务
*
* @return
* @description
*/
@RequestMapping(path = "/job/planAstStatJob.json", method = RequestMethod.GET)
public BaseResult<Boolean> planAstStatJob() {
planAstStatJob.doExecute();
return BaseResult.success(null);
}
/**
* 资金资产任务Task生成Job
......@@ -269,18 +148,6 @@ public class JobController {
return BaseResult.success(null);
}
/**
* 查询账户余额
*
* @return
* @description
*/
@RequestMapping(path = "/acct/balance.json", method = RequestMethod.GET)
public Money acctBalance(String acctNo) {
return wkPayManager.balance(acctNo, WkChannelNoEnum.BC_YQ0001);
}
/**
* 查询账户余额
*
......@@ -321,74 +188,6 @@ public class JobController {
return BaseResult.success(cnt);
}
/**
* 月报手动生成
*
* @param planNo
* @param date
* @return
*/
@RequestMapping(path = "/report/month.json", method = RequestMethod.GET)
public BaseResult<Boolean> initMonthReport(@RequestParam String planNo, @RequestParam String date) {
PlanBase planBase = planManager.getPlanFullByNo(planNo);
VarChecker.checkNotNull(planBase, "错误的计划编号");
// 按日期生成月报
MutablePair<Boolean, String> rptResult =
wkPlanReportHandler.checkAndBuildMonthPlanReport(DateUtil.parseDate(date), planBase);
return BaseResult.success(rptResult);
}
/**
* 日报手动生成
*
* @param planNo
* @param date
* @return
*/
@RequestMapping(path = "/report/daily.json", method = RequestMethod.GET)
public BaseResult<Boolean> initDailyReport(@RequestParam String planNo, @RequestParam String date, Integer count) {
PlanBase planBase = planManager.getPlanFullByNo(planNo);
VarChecker.checkNotNull(planBase, "错误的计划编号");
List<String> planNosBySpvNo = Lists.newArrayList();
if (planBase.getPlanType() == PlanTypeEnum.SPV) {
planNosBySpvNo = planRepo.getPlanNosBySpvNo(planBase.getPlanNo());
}
int cnt = 1;
if (ToolUtil.isNotEmpty(count)) {
cnt = count;
}
Day trfDate = orgAcctDayComponent.getTrfAcctDay();
for (int i = 0; i < cnt; i++) {
Day acctDate = new Day(DateUtil.offsetDay(DateUtil.parseDate(date), i));
if (DayUtil.compare(trfDate, acctDate) <= 0) {
continue;
}
PlanReport planReport = planReportRepo.getReport(
planBase.getPlanNo(), ReportTypeEnum.RPT001, acctDate.getDayString());
if (planReport != null) {
continue;
}
DailyReportDateField reportDateField = new DailyReportDateField();
reportDateField.setRptDate(acctDate.getStandardDate());
// 上一日报表
PlanReport lastReport = planReportRepo.getReport(
planBase.getPlanNo(), ReportTypeEnum.RPT001, acctDate.getYesterday().getDayString());
// 按日期生成日报
wkPlanReportHandler.buildDailyAstReport(reportDateField, planBase, lastReport, planNosBySpvNo);
}
return BaseResult.success("日报生成成功");
}
/**
* 停止放款日后续动作
*
* @return
*/
@RequestMapping(path = "/job/orgcapital.json", method = RequestMethod.GET)
public BaseResult<Boolean> orgcapital() {
lenderOrgCapitalJob.doExecute();
return BaseResult.success(true);
}
}
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package com.abssqr.plat.web.controller.wkpay;
import javax.servlet.http.HttpServletRequest;
import com.abssqr.plat.common.util.loggers.CommonLoggers;
import com.abssqr.plat.core.service.wk.pay.WkPayManager;
import com.general.system.common.util.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.web.controller.callback.wkpay: WkPayController.java, v 0.1 2019-06-21 14:26
* bangis.wangdf Exp $
*/
@RestController
public class WkPayController {
@Autowired
private HttpServletRequest request;
@Autowired
private WkPayManager wkPayManager;
@RequestMapping(path = "callback/wkpay/trade")
@ResponseBody
public String tradeCallBack(@RequestParam(name = "msg") String msg) {
LogUtil.info(CommonLoggers.WK_INTEGRATION, "msg=[{0}]", msg);
return "success";
}
@RequestMapping(path = "/callback/wkpay/project")
@ResponseBody
public String project() {
wkPayManager.project();
return "success";
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment