Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
bb
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abs_pom
bb
Commits
1e6b317f
Commit
1e6b317f
authored
Apr 13, 2020
by
王德峰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bb 项目初始化
清理部分 清理wk任务
parent
da9236e7
Show whitespace changes
Inline
Side-by-side
Showing
43 changed files
with
10 additions
and
6829 deletions
+10
-6829
app/biz/service/src/main/java/com/abssqr/plat/biz/api/report/ReportServiceImpl.java
+0
-163
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyBackMatch/LoanAstBuyBackMatchExecutor.java
+0
-76
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyBackMatch/LoanAstBuyBackMatchLoader.java
+0
-87
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyBackMatch/LoanAstBuyBackMatchStarter.java
+0
-89
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyback/LoanAstBuyBackExecutor.java
+0
-121
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyback/LoanAstBuyBackLoader.java
+0
-120
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyback/LoanAstBuyBackStarter.java
+0
-89
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/capitalAssetMatch/PlanCapitalAssertMatchExecutor.java
+0
-150
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/capitalAssetMatch/PlanCapitalAssertMatchLoader.java
+0
-80
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/capitalAssetMatch/PlanCapitalAssertMatchStater.java
+0
-79
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/AstModCheckCommonTaskHandler.java
+0
-44
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/CapitalAstMatchHandler.java
+0
-407
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/CapitalAstUnMatchHandler.java
+0
-392
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/FinSerFeeHandler.java
+0
-16
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/LoanAstBuyBackHandler.java
+0
-59
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/LoanAstBuyBackMatchHandler.java
+0
-359
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/PlanAstReqHandler.java
+0
-209
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/PlanAstStatTaskHandler.java
+0
-151
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/PlanCashFrozenHandler.java
+0
-200
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/listener/PlanMonitorRecordEvent.java
+0
-44
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/listener/PlanMonitorRecordListener.java
+0
-117
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/PlanAstStatAmtUtil.java
+0
-91
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/ReportItemFilter.java
+0
-81
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/ReportStatMap.java
+0
-33
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/wk/WkAstReportBuilder.java
+0
-1181
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/wk/WkManagerReportBuilder.java
+0
-910
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/ConfigRefreshJob.java
+0
-36
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/ast/AutoBackJob.java
+0
-154
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/ast/ZLFinSerFeeJob.java
+0
-190
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/capitalAssertMatch/CapitalAssertMatchJob.java
+0
-197
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/keeper/node/CapitalAstMatchKeeper.java
+0
-117
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/plan/PlanDailyJob.java
+4
-9
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/plan/PlanPackJob.java
+0
-164
app/common/facade/src/main/java/com/abssqr/plat/common/facade/service/report/ReportService.java
+0
-43
app/test/src/test/java/com/abssqr/plat/test/BaseAutoTests.java
+5
-68
app/test/src/test/java/com/abssqr/plat/test/testlink/ast/ZLFinSerFeeJobTest.java
+0
-41
app/test/src/test/java/com/abssqr/plat/test/unittest/capitalAstMatch/CapitalAstMatchUnitTest.java
+0
-53
app/test/src/test/java/com/abssqr/plat/test/unittest/capitalAstUnMatch/CapitalAstUnMatchTest.java
+0
-56
app/test/src/test/java/com/abssqr/plat/test/unittest/job/CapitalAssertMatchJobTest.java
+0
-52
app/test/src/test/java/com/abssqr/plat/test/unittest/job/keeper/CapitalAstMatchKeeperTest.java
+0
-50
app/test/src/test/java/com/abssqr/plat/test/unittest/planBuyBack/PlanBuyBackMatchTest.java
+0
-56
app/web/src/main/java/com/abssqr/plat/web/controller/job/JobController.java
+1
-43
app/web/src/main/java/com/abssqr/plat/web/controller/report/ReportFormController.java
+0
-152
No files found.
app/biz/service/src/main/java/com/abssqr/plat/biz/api/report/ReportServiceImpl.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
api
.
report
;
import
com.abssqr.plat.biz.shared.report.wk.WkManagerReportBuilder
;
import
com.abssqr.plat.biz.support.ServiceSupport
;
import
com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum
;
import
com.abssqr.plat.common.facade.enums.ReportTypeEnum
;
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.wk.WkManagerReport
;
import
com.abssqr.plat.common.facade.param.base.CommonPlanQryParam
;
import
com.abssqr.plat.common.facade.param.reportForm.ReportFormAstParam
;
import
com.abssqr.plat.common.facade.param.reportForm.ReportFormMgrParam
;
import
com.abssqr.plat.common.facade.service.report.ReportService
;
import
com.abssqr.plat.common.facade.validation.Valid
;
import
com.abssqr.plat.common.model.exception.AbssqrBizException
;
import
com.abssqr.plat.common.model.repo.plan.PlanRepo
;
import
com.abssqr.plat.common.model.repo.report.PlanReportRepo
;
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
com.google.common.collect.Lists
;
import
org.apache.commons.collections.CollectionUtils
;
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
;
/**
*
* @author yangcheng
* @version ReportServiceImpl.java, v0.12019-07-0114:19 yangchengExp$
*/
@Component
public
class
ReportServiceImpl
extends
ServiceSupport
implements
ReportService
{
//打印日志问题:需要打印错误日志,开启服务日志,日志服务需要展示什么参数,然后在去查询,拼接业务数据然后返回;,并且起事务;
//设置时间段问题当前日期情况
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
ReportServiceImpl
.
class
);
@Autowired
private
PlanReportRepo
planReportRepo
;
@Autowired
private
WkManagerReportBuilder
wkManagerReportBuilder
;
@Autowired
private
PlanRepo
planRepo
;
/**
* 计划报表
* @param param
* @return
*/
@Override
public
WkManagerReport
getReportFormPlan
(
@Valid
ReportFormMgrParam
param
)
{
return
this
.
doQry
(
param
,
()
->
{
String
begin
=
param
.
getBeginTime
();
String
end
=
param
.
getEndTime
();
//检查能否解析日期字段
MonthReportDateField
beginField
=
new
MonthReportDateField
();
beginField
.
parse
(
begin
);
MonthReportDateField
endField
=
new
MonthReportDateField
();
endField
.
parse
(
end
);
Date
beginDate
=
DateTimeUtil
.
parseInTolerance
(
begin
);
Date
endDate
=
DateTimeUtil
.
parseInTolerance
(
end
);
dateJudge
(
beginDate
,
endDate
);
//当判断通过的时候打印日志
LogUtil
.
info
(
LOGGER
,
"计划报表统计:计划编号={0}, 开始时间={1}, 结束时间={2},"
,
param
.
getPlanNo
(),
begin
,
end
);
PlanBase
planBase
=
planRepo
.
getPlanByNo
(
param
.
getPlanNo
());
return
wkManagerReportBuilder
.
getReport
(
planBase
,
begin
,
end
);
});
}
/**
* 资产报表
* @param param
* @return
*/
@Override
public
List
<
PlanReport
>
getReportFormAst
(
@Valid
ReportFormAstParam
param
)
{
return
this
.
doQry
(
param
,
()
->
{
Date
beginDate
=
DateTimeUtil
.
parseInTolerance
(
param
.
getBeginDate
());
Date
endDate
=
DateTimeUtil
.
parseInTolerance
(
param
.
getEndDate
());
dateJudge
(
beginDate
,
endDate
);
LogUtil
.
info
(
LOGGER
,
"资产报表统计:计划编号={0}, 开始时间={1}, 结束时间={2},"
,
param
.
getPlanNo
(),
param
.
getBeginDate
(),
param
.
getEndDate
());
DailyReportDateField
beginField
=
new
DailyReportDateField
();
beginField
.
setRptDate
(
beginDate
);
DailyReportDateField
endField
=
new
DailyReportDateField
();
endField
.
setRptDate
(
endDate
);
return
planReportRepo
.
getPlansByDate
(
param
.
getPlanNo
(),
beginField
.
desc
(),
endField
.
desc
(),
ReportTypeEnum
.
RPT001
);
});
}
@Override
public
List
<
PlanReport
>
getReportFormMonthEnd
(
@Valid
CommonPlanQryParam
param
)
{
return
this
.
doQry
(
param
,
()
->
{
LogUtil
.
info
(
LOGGER
,
"资产报表统计:计划编号={0}"
,
param
.
getPlanNo
());
PlanBase
planBase
=
planRepo
.
getPlanByNo
(
param
.
getPlanNo
());
Date
effectDate
=
planBase
.
getEffectDate
();
Date
curDate
=
SystemDateUtil
.
getSystemDate
();
List
<
String
>
monthEndDate
=
Lists
.
newArrayList
();
Date
startDate
=
DateTimeUtil
.
parseFromYMD
(
DateTimeUtil
.
format
(
effectDate
,
DateTimeUtil
.
FORMAT_DATE_YYYYMM
)
+
"01"
);
// 当前日期所在月,肯定没有月报产生
while
(
DateTimeUtil
.
calMonthDiff
(
startDate
,
curDate
)
>
0
)
{
startDate
=
DateTimeUtil
.
addMonths
(
startDate
,
1
);
monthEndDate
.
add
(
DateTimeUtil
.
formatYMD
(
DateTimeUtil
.
addDays
(
startDate
,
-
1
)));
}
if
(
CollectionUtils
.
isEmpty
(
monthEndDate
))
{
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"计划生效日期[{0}]和当前日期[{1}]间,无法生成月末报表"
,
effectDate
,
curDate
));
}
return
planReportRepo
.
getPlansByDateList
(
param
.
getPlanNo
(),
ReportTypeEnum
.
RPT001
,
monthEndDate
);
});
}
private
boolean
dateJudge
(
Date
begin
,
Date
end
)
{
Date
nowTime
=
DateTimeUtil
.
getStandardDate
(
SystemDateUtil
.
getSystemDate
());
if
(
DateTimeUtil
.
calcDayDiff
(
end
,
begin
)
<
0
)
{
String
errorText
=
MessageUtil
.
formatMsg
(
"无法生成报表:结束时间{0}小于开始时间{1}"
,
end
,
begin
);
LogUtil
.
error
(
LOGGER
,
errorText
);
throw
new
AbssqrBizException
(
errorText
,
CommonErrorCodeEnum
.
INVALID_PARAM
);
}
if
(
DateTimeUtil
.
calcDayDiff
(
end
,
nowTime
)
>=
0
)
{
String
errorText
=
MessageUtil
.
formatMsg
(
"无法生成报表:结束时间[{0}]必须小于当前时间[{1}],否则报表还未生成"
,
end
,
nowTime
);
LogUtil
.
error
(
LOGGER
,
errorText
);
throw
new
AbssqrBizException
(
errorText
,
CommonErrorCodeEnum
.
INVALID_PARAM
);
}
return
true
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyBackMatch/LoanAstBuyBackMatchExecutor.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
buyBackMatch
;
import
com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutorTemp
;
import
com.abssqr.plat.biz.shared.handler.LoanAstBuyBackMatchHandler
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.repo.task.CommonTaskRepository
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.LogUtil
;
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
;
/**
* 资产回购匹配执行器
*/
@Component
public
class
LoanAstBuyBackMatchExecutor
extends
DispatcherExecutorTemp
<
CommonTask
>
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
LoanAstBuyBackMatchExecutor
.
class
);
@Autowired
private
CommonTaskRepository
commonTaskRepository
;
@Autowired
private
LoanAstBuyBackMatchHandler
loanAstBuyBackMatchHandler
;
@Override
public
CommonTask
doExecute
(
CommonTask
node
)
{
LogUtil
.
info
(
LOGGER
,
"执行回购匹配任务[{0}]-start"
,
node
.
getContext
());
loanAstBuyBackMatchHandler
.
execute
(
node
.
getContext
(),
status
->
{
if
(
TaskStatusEnum
.
SUCCESS
==
status
)
{
node
.
setTaskStatus
(
status
);
markSuccess
(
node
);
}
else
{
markFail
(
node
,
"执行回购匹配任务失败"
);
}
LogUtil
.
info
(
LOGGER
,
"执行回购匹配任务[{0}]-end,status=[{1}]"
,
node
.
getContext
(),
status
);
});
return
node
;
}
@Override
protected
CommonTask
markSuccess
(
CommonTask
node
)
{
commonTaskRepository
.
updateTaskStatus
(
node
.
getId
(),
TaskStatusEnum
.
SUCCESS
,
TaskStatusEnum
.
EXECUTING
,
""
);
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
LoanAstBuyBackMatchStarter
.
JOB_NAME
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyBackMatch/LoanAstBuyBackMatchLoader.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
buyBackMatch
;
import
com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader
;
import
com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
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.task.AstSyncTaskCtrRepo
;
import
com.abssqr.plat.common.model.repo.task.CommonTaskRepository
;
import
com.abssqr.plat.core.service.ast.LoanAstBuyBackManager
;
import
com.abssqr.plat.core.service.host.HostManager
;
import
com.general.system.common.util.SystemDateUtil
;
import
com.general.system.common.util.ThreadUtil
;
import
com.general.system.common.util.VarChecker
;
import
org.apache.commons.collections.CollectionUtils
;
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.stream.Collectors
;
/**
* 资产转让
*
* @author bangis.wangdf
* @version com.abssqr.plat.biz.shared.task.task: AstTrTaskLoader.java, v 0.1 2018-01-08 00:59 hongwei.wang Exp $
*/
@Component
public
class
LoanAstBuyBackMatchLoader
implements
DispatcherLoader
<
CommonTask
>
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
LoanAstBuyBackMatchLoader
.
class
);
@Autowired
private
TransactionTemplate
transactionTemplate
;
@Autowired
private
JobControlRepository
jobControlRepository
;
@Autowired
private
CommonTaskRepository
commonTaskRepository
;
@Autowired
private
HostManager
hostManager
;
private
static
long
sleepTime
=
1000
*
60
;
/**
* 装载待分发节点
*
* @param size
* @return
*/
@Override
public
List
<
CommonTask
>
loadToDoNodes
(
int
size
)
{
ThreadUtil
.
sleep
(
sleepTime
,
LOGGER
);
return
transactionTemplate
.
execute
(
transactionStatus
->
{
// job加锁
jobControlRepository
.
lockByJobName
(
LoanAstBuyBackMatchStarter
.
JOB_NAME
);
// 获取回购筛选任务
List
<
CommonTask
>
existsTask
=
commonTaskRepository
.
selectUnifinishTaskByType
(
CommonTaskTypeEnum
.
BUY_BACK_MATCH
);
// 过滤 排除非初始化的和下次执行时间大于当前时间的任务
existsTask
=
existsTask
.
stream
()
.
filter
(
item
->
item
.
getTaskStatus
()
==
TaskStatusEnum
.
INIT
&&
SystemDateUtil
.
getSystemDate
().
compareTo
(
item
.
getNextExecTime
())
>
0
)
.
collect
(
Collectors
.
toList
());
if
(
CollectionUtils
.
isNotEmpty
(
existsTask
))
{
int
cnt
=
commonTaskRepository
.
updateTaskExec
(
SystemDateUtil
.
getSystemDate
(),
hostManager
.
getHostInfo
().
getHostName
(),
existsTask
);
VarChecker
.
checkArgument
(
cnt
==
existsTask
.
size
(),
"[LoanAstBuyBackMatchLoader] - 更新条数与预期不符,可能存在并发问题"
);
}
return
existsTask
;
});
}
/**
* 设置休眠时间 测试用
* @param time
*/
public
void
setSleepTime
(
Long
time
){
sleepTime
=
time
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyBackMatch/LoanAstBuyBackMatchStarter.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
buyBackMatch
;
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.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.biz.shared.task.task: AstTrTaskDispatcherManager.java, v 0.1 2018-01-08 02:42 hongwei
* .wang Exp $
*/
@Component
public
class
LoanAstBuyBackMatchStarter
extends
DispatcherStarter
<
CommonTask
>
{
@Autowired
private
LoanAstBuyBackMatchExecutor
loanAstBuyBackMatchExecutor
;
@Autowired
private
LoanAstBuyBackMatchLoader
loanAstBuyBackMatchLoader
;
@Autowired
private
HostManager
hostManager
;
@Autowired
private
CommonTaskRepository
commonTaskRepository
;
public
static
String
JOB_NAME
=
"LoanAstBuyBackMatchStarter"
;
@Value
(
"${dispatcher.buyBack.coreSize}"
)
private
int
coreSize
;
@Value
(
"${dispatcher.buyBack.maxSize}"
)
private
int
maxSize
;
@Value
(
"${dispatcher.buyBack.hungrySize}"
)
private
int
hungrySize
;
@Value
(
"${dispatcher.buyBack.queueSize}"
)
private
int
queueSize
=
200
;
@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
loanAstBuyBackMatchLoader
;
}
@Override
protected
DispatcherExecutor
<
CommonTask
>
getExecutor
()
{
return
loanAstBuyBackMatchExecutor
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyback/LoanAstBuyBackExecutor.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
buyback
;
import
com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutorTemp
;
import
com.abssqr.plat.biz.shared.handler.LoanAstBuyBackHandler
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.TrTaskDAO
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.model.domain.task.TrTask
;
import
com.abssqr.plat.common.model.repo.tr.TrTaskRepo
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.SystemDateUtil
;
import
org.apache.commons.lang3.StringUtils
;
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 hanfei
* @version $Id: LoanAstBuyBackExecutor.java, v 0.1 2020-02-11 5:12 PM hanfei Exp $
*/
@Component
public
class
LoanAstBuyBackExecutor
extends
DispatcherExecutorTemp
<
TrTask
>
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
LoanAstBuyBackExecutor
.
class
);
// 单位(秒)
private
final
static
int
DEFAULT_STEP
=
5
;
@Autowired
private
LoanAstBuyBackHandler
loanAstBuyBackHandler
;
@Autowired
private
TrTaskRepo
trTaskRepo
;
@Override
public
TrTask
doExecute
(
TrTask
node
)
{
LogUtil
.
info
(
LOGGER
,
"回购处理astNo[{0}]batchNo[{1}]packType[{2}]"
,
node
.
getAstNo
(),
node
.
getBatchNo
(),
node
.
getPackType
());
boolean
result
=
false
;
Date
befDt
=
SystemDateUtil
.
getSystemDate
();
try
{
// 加锁捞取 幂等判断
TrTask
lockedNode
=
trTaskRepo
.
lockByIdNowait
(
node
.
getId
());
if
(
null
==
lockedNode
||
lockedNode
.
getTaskStatus
()
!=
TaskStatusEnum
.
EXECUTING
)
{
LogUtil
.
warn
(
LOGGER
,
"资产回购任务[{0}]状态[{1}]不为执行中,可能存在并发问题"
,
node
.
getId
(),
(
lockedNode
!=
null
)
?
lockedNode
.
getTaskStatus
()
:
"-"
);
return
lockedNode
;
}
// 执行回购交易操作
result
=
loanAstBuyBackHandler
.
astBuyBackExecute
(
node
);
if
(
result
)
{
return
markSuccess
(
node
);
}
else
{
LogUtil
.
error
(
LOGGER
,
"资产回购任务[{0}]状态[{1}]执行失败"
,
node
.
getAstNo
(),
node
);
return
markFail
(
node
,
"资产回购执行失败"
);
}
}
finally
{
Date
endDt
=
SystemDateUtil
.
getSystemDate
();
LogUtil
.
info
(
LOGGER
,
"[LoanAstBuyBackExecutor] astId=[{0}], res={1}, elipse={2}ms"
,
node
.
getAstNo
(),
result
,
(
endDt
.
getTime
()
-
befDt
.
getTime
()));
}
}
@Autowired
private
TrTaskDAO
trTaskDAO
;
/**
* 标记成功
*
* @param node
*/
@Override
protected
TrTask
markSuccess
(
TrTask
node
)
{
node
.
setTaskStatus
(
TaskStatusEnum
.
SUCCESS
);
trTaskDAO
.
updateTaskStatus
(
node
.
getId
(),
""
,
TaskStatusEnum
.
SUCCESS
.
getCode
());
return
node
;
}
/**
* 标记失败
*
* @param node
* @param failMessage
*/
@Override
protected
TrTask
markFail
(
TrTask
node
,
String
failMessage
)
{
node
.
setTaskStatus
(
TaskStatusEnum
.
FAILURE
);
trTaskDAO
.
updateTaskStatus
(
node
.
getId
(),
failMessage
,
TaskStatusEnum
.
FAILURE
.
getCode
());
return
node
;
}
/**
* 标记异常
*
* @param node
* @param failMessage
*/
@Override
protected
TrTask
markException
(
TrTask
node
,
String
failMessage
)
{
if
(
StringUtils
.
isBlank
(
failMessage
))
{
failMessage
=
"回购交易执行失败"
;
}
node
.
setTaskStatus
(
TaskStatusEnum
.
INIT
);
trTaskDAO
.
updateTaskExep
(
DateTimeUtil
.
addSecond
(
SystemDateUtil
.
getSystemDate
(),
DEFAULT_STEP
),
node
.
getId
(),
failMessage
.
length
()
>
2000
?
failMessage
.
substring
(
0
,
1990
)
:
failMessage
);
return
node
;
}
@Override
protected
String
getName
()
{
return
LoanAstBuyBackStarter
.
BUY_BACK_NAME
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyback/LoanAstBuyBackLoader.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
buyback
;
import
com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.TrTaskDAO
;
import
com.abssqr.plat.common.dal.mysql.auto.dataobject.TrTaskDO
;
import
com.abssqr.plat.common.facade.enums.AstPackTradeTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.model.convertor.TrTaskConvert
;
import
com.abssqr.plat.common.model.domain.ast.LoanAstBuyBackPack
;
import
com.abssqr.plat.common.model.domain.task.TrCtrTask
;
import
com.abssqr.plat.common.model.domain.task.TrTask
;
import
com.abssqr.plat.common.model.repo.tr.TrCtrTaskRepo
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.ast.LoanAstBuyBackManager
;
import
com.abssqr.plat.core.service.host.HostManager
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.SystemDateUtil
;
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
;
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.Date
;
import
java.util.List
;
/**
* 回购转让交易任务捞取
* @author hanfei
* @version $Id: LoanAstBuyBackLoader.java, v 0.1 2020-02-11 5:15 PM hanfei Exp $
*/
@Component
public
class
LoanAstBuyBackLoader
implements
DispatcherLoader
<
TrTask
>
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
LoanAstBuyBackLoader
.
class
);
@Autowired
private
TrTaskDAO
trTaskDAO
;
@Autowired
private
TransactionTemplate
transactionTemplate
;
@Autowired
private
HostManager
hostManager
;
@Autowired
private
TrCtrTaskRepo
trCtrTaskRepo
;
@Autowired
private
LoanAstBuyBackManager
loanAstBuyBackManager
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
/**
* 装载待分发节点
*
* @param size
* @return
*/
@Override
public
List
<
TrTask
>
loadToDoNodes
(
int
size
)
{
Date
curDate
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
// 1、捞取回购任务总控STATUS为init
List
<
TrCtrTask
>
trCtrTasks
=
trCtrTaskRepo
.
queryInitCtrTaskList
(
curDate
,
TaskStatusEnum
.
INIT
,
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
if
(
ToolUtil
.
isEmpty
(
trCtrTasks
))
{
return
Lists
.
newArrayList
();
}
TrCtrTask
trCtrTask
=
null
;
for
(
TrCtrTask
one
:
trCtrTasks
){
// 2、捞取对应回购筛选包校验 PACK_STATUS为SCEEN_FIS 和 APPROVE_STATUS为PASSED
LoanAstBuyBackPack
pack
=
loanAstBuyBackManager
.
getByPackCode
(
one
.
getPackCode
());
if
(
pack
.
canExec
()){
trCtrTask
=
one
;
break
;
}
}
// 没有可执行任务
if
(
trCtrTask
==
null
){
return
Lists
.
newArrayList
();
}
Long
canExecId
=
trCtrTask
.
getId
();
return
transactionTemplate
.
execute
(
transactionStatus
->
{
TrCtrTask
lockedCtrTask
=
trCtrTaskRepo
.
lockById
(
canExecId
);
if
(
lockedCtrTask
.
getTaskStatus
()
!=
TaskStatusEnum
.
INIT
)
{
return
Lists
.
newArrayList
();
}
Long
undoCnt
=
trTaskDAO
.
cntInitTaskByBatchNo
(
lockedCtrTask
.
getBatchNo
());
if
(
undoCnt
==
0
)
{
LogUtil
.
info
(
LOGGER
,
"转让控制[{0}]无待转任务,标记结束"
,
lockedCtrTask
);
trCtrTaskRepo
.
updateStatus
(
lockedCtrTask
.
getId
(),
TaskStatusEnum
.
SUCCESS
);
return
Lists
.
newArrayList
();
}
trCtrTaskRepo
.
updateExecTms
(
lockedCtrTask
.
getId
(),
lockedCtrTask
.
getExecTimes
()
+
1
);
// 3、捞取回购资产任务TASK_STATUS为init
List
<
TrTaskDO
>
taskDOS
=
trTaskDAO
.
selectInitTask
(
SystemDateUtil
.
getSystemDate
(),
Long
.
valueOf
(
size
),
lockedCtrTask
.
getBatchNo
(),
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
.
getCode
());
if
(
CollectionUtils
.
isEmpty
(
taskDOS
))
{
return
Lists
.
newArrayList
();
}
// 4、更新任务TASK_STATUS为exec
int
count
=
trTaskDAO
.
updateTaskExec
(
SystemDateUtil
.
getSystemDate
(),
hostManager
.
getHostInfo
().
getHostName
(),
taskDOS
);
VarChecker
.
checkEquals
(
count
,
taskDOS
.
size
(),
"[TaskLoader.loadToDoNodes]更新任务数跟期望数不一致,实际更新:{0},期望更新:{1}"
,
count
,
taskDOS
.
size
());
LogUtil
.
info
(
LOGGER
,
"转让控制[{0}]捞取[{1}]待执行任务"
,
lockedCtrTask
,
count
);
return
TrTaskConvert
.
convertDTOs
(
taskDOS
);
});
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/buyback/LoanAstBuyBackStarter.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
buyback
;
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.dal.mysql.auto.dao.TrTaskDAO
;
import
com.abssqr.plat.common.facade.enums.AstPackTradeTypeEnum
;
import
com.abssqr.plat.common.model.domain.task.TrTask
;
import
com.abssqr.plat.core.service.host.HostManager
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.stereotype.Component
;
/**
* 回购转让交易任务组件绑定
* @author hanfei
* @version $Id: LoanAstBuyBackLoader.java, v 0.1 2020-02-11 5:15 PM hanfei Exp $
*/
@Component
public
class
LoanAstBuyBackStarter
extends
DispatcherStarter
<
TrTask
>
{
@Autowired
private
LoanAstBuyBackExecutor
loanAstBuyBackExecutor
;
@Autowired
private
LoanAstBuyBackLoader
loanAstBuyBackLoader
;
@Autowired
private
HostManager
hostManager
;
@Autowired
private
TrTaskDAO
trTaskDAO
;
@Value
(
"${dispatcher.tr.coreSize}"
)
private
int
coreSize
;
@Value
(
"${dispatcher.tr.maxSize}"
)
private
int
maxSize
;
@Value
(
"${dispatcher.tr.hungrySize}"
)
private
int
hungrySize
;
@Value
(
"${dispatcher.tr.queueSize}"
)
private
int
queueSize
=
200
;
@Override
protected
void
recovery
()
{
trTaskDAO
.
updateHangTasksByIp
(
hostManager
.
getHostInfo
().
getHostName
(),
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
.
getCode
());
}
public
static
String
BUY_BACK_NAME
=
"LoanAstBuyBackStarter"
;
@Override
public
String
getName
()
{
return
BUY_BACK_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
<
TrTask
>
getLoader
()
{
return
loanAstBuyBackLoader
;
}
@Override
protected
DispatcherExecutor
<
TrTask
>
getExecutor
()
{
return
loanAstBuyBackExecutor
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/capitalAssetMatch/PlanCapitalAssertMatchExecutor.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
capitalAssetMatch
;
import
com.abssqr.plat.biz.shared.dispatcher.DispatcherExecutorTemp
;
import
com.abssqr.plat.biz.shared.handler.CapitalAstMatchHandler
;
import
com.abssqr.plat.biz.shared.handler.CapitalAstUnMatchHandler
;
import
com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.exception.AbssqrBizException
;
import
com.abssqr.plat.common.model.repo.task.CommonTaskRepository
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.general.system.common.model.exception.BaseCommonException
;
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.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.Date
;
/**
* 资金资产绑定/解绑
*/
@Component
public
class
PlanCapitalAssertMatchExecutor
extends
DispatcherExecutorTemp
<
CommonTask
>
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanCapitalAssertMatchExecutor
.
class
);
@Autowired
CommonTaskRepository
commonTaskRepository
;
@Autowired
CapitalAstMatchHandler
capitalAstMatchHandler
;
@Autowired
CapitalAstUnMatchHandler
capitalAstUnMatchHandler
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
@Autowired
TransactionTemplate
transactionTemplate
;
@Override
protected
CommonTask
doExecute
(
CommonTask
node
)
{
Date
absAccountDate
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
StringBuilder
failMessage
=
new
StringBuilder
();
boolean
isSucc
=
true
;
switch
(
node
.
getTaskType
())
{
//解绑任务
case
CAPTITALASSERT_UNMATCH:
{
LogUtil
.
info
(
LOGGER
,
"执行资金资产解绑-start"
,
node
.
getContext
());
String
allocNo
=
node
.
getBizNo
();
String
planNo
=
node
.
getContext
();
try
{
isSucc
=
transactionTemplate
.
execute
(
status
->
{
return
capitalAstUnMatchHandler
.
execute
(
planNo
,
allocNo
,
absAccountDate
);
});
}
catch
(
Exception
e
){
LogUtil
.
error
(
LOGGER
,
"计划编号[{0}],兑付单编号[{1}]执行资金资产解绑失败错误信息:[3]"
,
planNo
,
allocNo
,
e
.
getMessage
());
isSucc
=
false
;
failMessage
.
append
(
e
.
getMessage
());
}
markStatus
(
isSucc
,
node
,
failMessage
.
toString
());
LogUtil
.
info
(
LOGGER
,
"执行资金资产解绑-end"
,
node
.
getContext
());
break
;
}
//解绑匹配任务
case
UNMATCH_CAPTITALASSERT_MATCH:
{
try
{
isSucc
=
transactionTemplate
.
execute
(
status
->
{
return
doMatch
(
node
);
});
}
catch
(
Exception
e
){
LogUtil
.
error
(
LOGGER
,
"计划编号[{0}]执行资金资产匹配败错误信息:[3]"
,
node
.
getContext
(),
e
.
getMessage
());
isSucc
=
false
;
failMessage
.
append
(
e
.
getMessage
());
}
markStatus
(
isSucc
,
node
,
failMessage
.
toString
());
break
;
}
//同步匹配任务
case
SYNC_CAPTITALASSERT_MATCH:
{
try
{
isSucc
=
transactionTemplate
.
execute
(
status
->
{
return
doMatch
(
node
);
});
}
catch
(
Exception
e
){
LogUtil
.
error
(
LOGGER
,
"计划编号[{0}]执行资金资产匹配败错误信息:[3]"
,
node
.
getContext
(),
e
.
getMessage
());
isSucc
=
false
;
failMessage
.
append
(
e
.
getMessage
());
}
markStatus
(
isSucc
,
node
,
failMessage
.
toString
());
break
;
}
default
:{
throw
new
BaseCommonException
(
"不支持的任务类型:"
+
node
.
getTaskType
().
getCode
());
}
}
return
node
;
}
private
boolean
doMatch
(
CommonTask
node
){
LogUtil
.
info
(
LOGGER
,
"执行解绑匹配-start"
,
node
.
getContext
());
String
bizNo
=
node
.
getBizNo
();
String
[]
split
=
bizNo
.
split
(
"-"
);
if
(
split
==
null
){
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"Id为[{0}]的CommonTaskBizNo有误 "
,
node
.
getId
()),
CommonErrorCodeEnum
.
INVALID_PARAM
,
false
);
}
String
planNo
=
node
.
getContext
();
String
accDateStr
=
split
[
2
];
Date
acctDate
=
DateTimeUtil
.
parseFromYMD
(
accDateStr
);
boolean
ret
=
capitalAstMatchHandler
.
execute
(
planNo
,
acctDate
);
LogUtil
.
info
(
LOGGER
,
"执行解绑匹配-end"
,
node
.
getContext
());
return
ret
;
}
private
void
markStatus
(
Boolean
status
,
CommonTask
node
,
String
errorMessage
){
if
(
status
){
markSuccess
(
node
);
return
;
}
markFail
(
node
,
errorMessage
);
}
@Override
protected
CommonTask
markSuccess
(
CommonTask
node
)
{
//为保证数据一直性,讲成功设置
commonTaskRepository
.
updateTaskStatus
(
node
.
getId
(),
TaskStatusEnum
.
SUCCESS
,
TaskStatusEnum
.
EXECUTING
,
""
);
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
.
updateTaskStatus
(
node
.
getId
(),
TaskStatusEnum
.
IGNORE
,
TaskStatusEnum
.
EXECUTING
,
""
);
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
"PlanCapitalAssertMatchExecutor"
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/capitalAssetMatch/PlanCapitalAssertMatchLoader.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
capitalAssetMatch
;
import
com.abssqr.plat.biz.shared.dispatcher.DispatcherLoader
;
import
com.abssqr.plat.common.facade.enums.PlanTypeEnum
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
import
com.abssqr.plat.common.facade.model.plan.PlanBase
;
import
com.abssqr.plat.common.model.domain.job.JobControl
;
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.task.CommonTaskRepository
;
import
com.abssqr.plat.core.service.host.HostManager
;
import
com.google.common.collect.Lists
;
import
org.apache.commons.collections.CollectionUtils
;
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.ArrayList
;
import
java.util.Date
;
import
java.util.List
;
@Component
public
class
PlanCapitalAssertMatchLoader
implements
DispatcherLoader
<
CommonTask
>
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanCapitalAssertMatchLoader
.
class
);
@Autowired
PlanRepo
planRepo
;
@Autowired
CommonTaskRepository
commonTaskRepository
;
@Autowired
private
HostManager
hostManager
;
@Autowired
private
TransactionTemplate
transactionTemplate
;
@Autowired
JobControlRepository
jobControlRepository
;
@Autowired
PlanCapitalAssertMatchExecutor
planCapitalAssertMatchExecutor
;
@Override
public
List
<
CommonTask
>
loadToDoNodes
(
int
size
)
{
List
<
CommonTask
>
commonTasksList
=
new
ArrayList
<>();
transactionTemplate
.
execute
(
transactionStatus
->{
JobControl
jobControl
=
jobControlRepository
.
lockByJobName
(
planCapitalAssertMatchExecutor
.
getName
());
if
(
jobControl
==
null
||
jobControl
.
getIsEff
()==
YNEnum
.
N
){
return
false
;
}
// LogUtil.info(LOGGER,"[PlanCapitalAssertMatchLoader] 捞取资金资产匹配/解绑任务开始");
List
<
PlanBase
>
plans
=
planRepo
.
getAllPlanAstByType
(
PlanTypeEnum
.
SPV
.
getCode
());
for
(
PlanBase
plan:
plans
){
String
planNo
=
plan
.
getPlanNo
();
//查询是否有正在执行中的解绑/匹配任务
List
<
CommonTask
>
runningCommonTask
=
commonTaskRepository
.
queryExecUnMatchOrMatchTaskByContext
(
planNo
);
if
(
CollectionUtils
.
isNotEmpty
(
runningCommonTask
)){
continue
;
}
//查询初始化的匹配任务
List
<
CommonTask
>
initCommonTask
=
commonTaskRepository
.
queryInitUnMatchOrMatchTaskByContext
(
planNo
);
if
(
CollectionUtils
.
isNotEmpty
(
initCommonTask
)){
CommonTask
commonTask
=
initCommonTask
.
get
(
0
);
int
cnt
=
commonTaskRepository
.
updateTaskExec
(
new
Date
(),
hostManager
.
getHostInfo
().
getHostName
(),
Lists
.
newArrayList
(
commonTask
));
if
(
cnt
==
1
){
commonTasksList
.
add
(
commonTask
);
}
}
}
// LogUtil.info(LOGGER,"[PlanCapitalAssertMatchLoader] 捞取资金资产匹配/解绑任务结束");
return
true
;
});
return
commonTasksList
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/dispatcher/capitalAssetMatch/PlanCapitalAssertMatchStater.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
biz
.
shared
.
dispatcher
.
capitalAssetMatch
;
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.biz.shared.dispatcher.match.PlanAstMatchDispatcherExecutor
;
import
com.abssqr.plat.biz.shared.dispatcher.match.PlanAstMatchDispatcherLoader
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo
;
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.context.annotation.Configuration
;
import
org.springframework.stereotype.Component
;
@Configuration
@Component
public
class
PlanCapitalAssertMatchStater
extends
DispatcherStarter
<
CommonTask
>
{
@Autowired
HostManager
hostManager
;
@Autowired
AstSyncTaskCtrRepo
astSyncTaskCtrRepo
;
@Autowired
CommonTaskRepository
commonTaskRepository
;
@Autowired
PlanCapitalAssertMatchLoader
planCapitalAssertMatchLoader
;
@Autowired
PlanCapitalAssertMatchExecutor
planCapitalAssertMatchExecutor
;
public
static
String
JOB_NAME
=
"PlanCapitalAssertMatchStater"
;
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
getLoader
()
{
return
planCapitalAssertMatchLoader
;
}
@Override
protected
DispatcherExecutor
getExecutor
()
{
return
planCapitalAssertMatchExecutor
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/AstModCheckCommonTaskHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
javax.annotation.PostConstruct
;
import
com.abssqr.plat.biz.shared.dispatcher.commonTask.CommonTaskExecutor
;
import
com.abssqr.plat.common.dal.sync.auto.dao.WkAbsMfsBillCtrIgnoreDAO
;
import
com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.repo.ast.LoanRepository
;
import
com.general.system.common.util.VarChecker
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.biz.shared.handler: AstModCheckCommonTaskHandler.java, v 0.1 2020-03-04 14:06 bangis
* .wangdf Exp $
*/
@Component
public
class
AstModCheckCommonTaskHandler
implements
CommonTaskHandler
{
@Autowired
CommonTaskExecutor
commonTaskExecutor
;
@Autowired
WkAbsMfsBillCtrIgnoreDAO
wkAbsMfsBillCtrIgnoreDAO
;
@Autowired
LoanRepository
loanRepository
;
@PostConstruct
public
void
registerHandler
()
{
commonTaskExecutor
.
registerHandler
(
CommonTaskTypeEnum
.
AST_MOD_CHECK
,
this
);
}
@Override
public
CommonTask
execute
(
CommonTask
commonTask
)
{
VarChecker
.
checkEquals
(
commonTask
.
getTaskType
(),
CommonTaskTypeEnum
.
AST_MOD_CHECK
,
"CommonTask类型不为AST_MOD_CHECK,taskType={0}"
,
commonTask
.
getTaskType
());
//loanRepository.
return
null
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/CapitalAstMatchHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
import
com.abssqr.plat.common.dal.mysql.auto.paging.CapitalAstMatchPage
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.AstScale
;
import
com.abssqr.plat.common.facade.constants.LoanExtInfConstants
;
import
com.abssqr.plat.common.facade.enums.EventCodeEnum
;
import
com.abssqr.plat.common.facade.enums.OwnStatusEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.facade.enums.TransCodeEnum
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
import
com.abssqr.plat.common.facade.model.plan.InvestStructure
;
import
com.abssqr.plat.common.facade.model.plan.PlanAcctTitle
;
import
com.abssqr.plat.common.model.domain.ast.Loan
;
import
com.abssqr.plat.common.model.domain.ast.LoanAstGroup
;
import
com.abssqr.plat.common.model.domain.ast.LoanBak
;
import
com.abssqr.plat.common.model.domain.job.JobControl
;
import
com.abssqr.plat.common.model.domain.loanTrans.LoanTransDetail
;
import
com.abssqr.plat.common.model.domain.loanTrans.TransInfoTemplate
;
import
com.abssqr.plat.common.model.repo.ast.LoanBakRepo
;
import
com.abssqr.plat.common.model.repo.ast.LoanRepository
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
import
com.abssqr.plat.common.model.repo.loanTrans.LoanLogRepository
;
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.tr.TrTaskRepo
;
import
com.abssqr.plat.common.model.seq.SequenceUtil
;
import
com.abssqr.plat.common.util.profiler.PerformTrace
;
import
com.abssqr.plat.common.util.profiler.PerformTraceContext
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.ast.LoanAstAssembler
;
import
com.abssqr.plat.core.service.plan.PlanInvestStructureManager
;
import
com.abssqr.plat.core.service.system.TimeStampUtil
;
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.SystemDateUtil
;
import
com.general.system.common.util.VarChecker
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
org.apache.commons.collections.MapUtils
;
import
org.apache.commons.lang3.StringUtils
;
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.math.BigDecimal
;
import
java.util.Comparator
;
import
java.util.Date
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
static
com
.
abssqr
.
plat
.
common
.
model
.
enums
.
IdTypeEnum
.
CAP_AST_MATCH
;
/**
* 资金资产匹配
*
* @author xiachenxiang
* @version com.abssqr.plat.biz.shared.handler: CapitalAstMatchHandler.java, v 0.1 2020-02-03 2:22 PM xiachenxiang Exp $
*/
@Component
public
class
CapitalAstMatchHandler
{
private
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
getClass
());
@Autowired
private
TrTaskRepo
trTaskRepo
;
@Autowired
private
PlanInvestStructureManager
planInvestStructureManager
;
@Autowired
private
PlanAcctTitleRepo
planAcctTitleRepo
;
@Autowired
private
LoanBakRepo
loanBakRepo
;
@Autowired
private
LoanRepository
loanRepository
;
@Autowired
private
TransactionTemplate
transactionTemplate
;
@Autowired
private
LoanAstAssembler
loanAstAssembler
;
@Autowired
private
LoanLogRepository
loanLogRepository
;
@Autowired
private
PlanAllocRepo
planAllocRepo
;
@Autowired
private
JobControlRepository
jobControlRepository
;
@Autowired
private
CapitalAssertMatchJob
capitalAssertMatchJob
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
private
int
queryLimit
=
2000
;
/**
* @param planNo 计划编号
* @param taskCreateDay 任务创建日
* @return
*/
@PerformTrace
(
name
=
"CapitalAstMatchHandler"
)
public
boolean
execute
(
String
planNo
,
Date
taskCreateDay
)
{
// 1. 判断是否可进行资金匹配
// 判断转让、回购任务是否全部完成 ignore、init、exec
Long
cnt
=
trTaskRepo
.
cntTrTaskByTfrOut
(
planNo
,
Lists
.
newArrayList
(
TaskStatusEnum
.
IGNORE
.
getCode
(),
TaskStatusEnum
.
INIT
.
getCode
(),
TaskStatusEnum
.
EXECUTING
.
getCode
()),
null
);
VarChecker
.
checkArgument
(
cnt
.
equals
(
0L
),
"[CapitalAstMatchHandler] - [{0}]转让任务未完成"
,
planNo
);
// 判断会计日是否相等
Date
standardDate
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
if
(!
DateTimeUtil
.
isSameDay
(
standardDate
,
taskCreateDay
))
{
LogUtil
.
error
(
LOGGER
,
"[CapitalAstMatchHandler] - [{0}]资金匹配计划匹配日期为[{1}],当前会计日为[{2}],跳过"
,
planNo
,
DateTimeUtil
.
formatYMD
(
taskCreateDay
),
DateTimeUtil
.
formatYMD
(
standardDate
));
return
true
;
}
// LogUtil.info(LOGGER, "[CapitalAstMatchHandler] - [{0}]开始资金资产匹配", planNo);
// 2. 计算每个投资层级资金应该匹配多少资产
// 可用资金=投资层级规模-待分配本金金额(已审批)
// 获取投资结构信息
List
<
InvestStructure
>
investStructureList
=
planInvestStructureManager
.
selectByPlanNo
(
planNo
);
// 升序
investStructureList
.
sort
(
Comparator
.
comparing
(
InvestStructure:
:
getLayerEndDate
));
Map
<
String
,
Money
>
needMatchBalMap
=
this
.
calcNeedMatchMap
(
planNo
,
investStructureList
,
taskCreateDay
);
if
(
MapUtils
.
isEmpty
(
needMatchBalMap
))
{
LogUtil
.
info
(
LOGGER
,
"[CapitalAstMatchHandler] - [{0}]计划剩余需匹配投资结构为0"
,
planNo
);
return
true
;
}
// 3. 执行资金资产匹配
boolean
match
=
executeMatch
(
planNo
,
needMatchBalMap
,
investStructureList
,
taskCreateDay
);
LogUtil
.
info
(
LOGGER
,
"[CapitalAstMatchHandler] - [{0}]结束资金资产匹配 - result [{1}]"
,
planNo
,
match
);
return
match
;
}
/**
* 执行资金匹配
*
* @param planNo 计划编号
* @param needMatchBalMap 应匹金额
* @param investStructureList 投资结构
* @param taskCreateDay 任务创建日期
* @return
*/
private
boolean
executeMatch
(
String
planNo
,
Map
<
String
,
Money
>
needMatchBalMap
,
List
<
InvestStructure
>
investStructureList
,
Date
taskCreateDay
)
{
try
{
PerformTraceContext
.
enter
(
"CapitalAstMatchHandler.executeMatch"
);
// 资金资产匹配
CapitalAstMatchPage
capitalAstMatchPage
=
new
CapitalAstMatchPage
();
capitalAstMatchPage
.
setCurrPageNo
(
1
);
capitalAstMatchPage
.
setLimit
(
queryLimit
);
capitalAstMatchPage
.
setLenderOrgCode
(
planNo
);
boolean
match
=
true
;
do
{
match
=
this
.
capitalAstMatch
(
capitalAstMatchPage
,
needMatchBalMap
,
investStructureList
,
taskCreateDay
,
planNo
);
if
(!
match
)
{
break
;
}
}
while
(
capitalAstMatchPage
.
hasNextPage
());
// 判断是否存在未匹配的资产
capitalAstMatchPage
=
loanRepository
.
queryForCapitalAstMatch
(
capitalAstMatchPage
);
if
(
capitalAstMatchPage
.
getTotal
()
>
0
)
{
LogUtil
.
warn
(
LOGGER
,
"[CapitalAstMatchHandler] - [{0}]结束资金资产匹配失败,剩余应批资产大于0"
,
planNo
);
match
=
false
;
}
return
match
;
}
finally
{
PerformTraceContext
.
leave
();
}
}
/**
* 计算每个投资层级资金应该匹配多少资产
*
* @param planNo 计划编号
* @param investStructureList 投资结构
* @param taskCreateDay 任务创建日期
* @return
*/
private
Map
<
String
,
Money
>
calcNeedMatchMap
(
String
planNo
,
List
<
InvestStructure
>
investStructureList
,
Date
taskCreateDay
)
{
// 获取本金科目
List
<
PlanAcctTitle
>
planAcctTitleList
=
planAcctTitleRepo
.
getByEntityNo
(
planNo
);
// 获取已审批未兑付的金额
Map
<
String
,
Money
>
willPayMoneyMap
=
planAllocRepo
.
queryApprovedNotPayMoneyGroupByLayerNo
(
planNo
);
Map
<
String
,
Money
>
balMap
=
Maps
.
newHashMap
();
Money
investStructureBalSum
=
new
Money
();
planAcctTitleList
.
forEach
(
item
->
{
if
(
item
.
getTitleType
().
isInvest
())
{
Money
money
=
item
.
getBal
().
clone
();
Money
willPayMoney
=
willPayMoneyMap
.
getOrDefault
(
item
.
getRefNo
(),
new
Money
());
money
.
subtractFrom
(
willPayMoney
);
// 负保护
VarChecker
.
checkArgument
(!
money
.
isNegtive
(),
"[CapitalAstMatchHandler] - [{0}]投资结构剩余应匹规模小于0"
,
item
.
getRefNo
());
balMap
.
put
(
item
.
getRefNo
(),
money
);
investStructureBalSum
.
addTo
(
money
);
}
});
VarChecker
.
checkArgument
(
investStructureList
.
size
()
==
balMap
.
size
(),
"[CapitalAstMatchHandler] - [{0}]投资结构与本金科目不一致"
,
planNo
);
// 2.2 计算资金比例
// 计算资金比例
Map
<
String
,
BigDecimal
>
rateMap
=
this
.
calcCapistalRate
(
investStructureList
,
balMap
,
investStructureBalSum
,
planNo
);
Money
astScaleSum
=
new
Money
();
// 获取信托资产规模
Map
<
String
,
Money
>
astScaleMap
=
this
.
getAstScaleMap
(
taskCreateDay
,
planNo
,
astScaleSum
);
// 计算目标匹配余额
this
.
calcNeedMatchBal
(
investStructureList
,
astScaleSum
,
astScaleMap
,
rateMap
,
investStructureBalSum
,
planNo
,
balMap
,
true
);
// 计算资金比例
rateMap
=
this
.
calcCapistalRate
(
investStructureList
,
balMap
,
investStructureBalSum
,
planNo
);
// 计算目标匹配余额
Map
<
String
,
Money
>
needMatchBalMap
=
this
.
calcNeedMatchBal
(
investStructureList
,
astScaleSum
,
astScaleMap
,
rateMap
,
investStructureBalSum
,
planNo
,
balMap
,
false
);
return
needMatchBalMap
;
}
/**
* @param taskCreateDay
* @param planNo
* @return
*/
private
Map
<
String
,
Money
>
getAstScaleMap
(
Date
taskCreateDay
,
String
planNo
,
Money
astScaleSum
)
{
List
<
AstScale
>
astScaleList
=
loanBakRepo
.
getAstScale
(
taskCreateDay
,
planNo
);
Map
<
String
,
Money
>
astScaleMap
=
Maps
.
newHashMap
();
astScaleList
.
forEach
(
item
->
{
astScaleSum
.
addTo
(
item
.
getPrinBal
());
astScaleMap
.
put
(
item
.
getCapitalNo
(),
item
.
getPrinBal
());
});
return
astScaleMap
;
}
/**
* 资金资产匹配
*
* @param capitalAstMatchPage 分页
* @param needMatchBalMap 匹配余额
* @param investStructureList 投资结构信息
* @param execDate 任务生成的会计日
* @return 匹配结果
*/
private
boolean
capitalAstMatch
(
CapitalAstMatchPage
capitalAstMatchPage
,
Map
<
String
,
Money
>
needMatchBalMap
,
List
<
InvestStructure
>
investStructureList
,
Date
execDate
,
String
planNo
)
{
boolean
match
=
true
;
//增加Job控制
JobControl
jobControl
=
jobControlRepository
.
selectByJobName
(
capitalAssertMatchJob
.
getJobName
());
if
(
jobControl
.
getIsEff
()
==
YNEnum
.
N
)
{
LogUtil
.
error
(
LOGGER
,
"计划[{0}]匹配失败,资金资产匹配任务运行中被关闭"
,
planNo
);
return
false
;
}
capitalAstMatchPage
=
loanRepository
.
queryForCapitalAstMatch
(
capitalAstMatchPage
);
List
<
String
>
astNoList
=
capitalAstMatchPage
.
getDatas
();
for
(
String
astNo
:
astNoList
)
{
try
{
PerformTraceContext
.
enter
(
"CapitalAstMatchHandler.capitalAstmatch"
);
match
=
transactionTemplate
.
execute
(
status
->
this
.
matchCapital
(
astNo
,
investStructureList
,
needMatchBalMap
,
execDate
,
planNo
));
}
finally
{
PerformTraceContext
.
leave
();
}
if
(!
match
)
{
break
;
}
}
return
match
;
}
/**
* 匹配资金
*
* @param astNo 资产编号
* @param investStructureList 投资结构 按到期日升序
* @param needMatchBalMap 投资结构对应剩余应匹配金额
* @param execDate 任务生成日期
* @return
*/
private
boolean
matchCapital
(
String
astNo
,
List
<
InvestStructure
>
investStructureList
,
Map
<
String
,
Money
>
needMatchBalMap
,
Date
execDate
,
String
planNo
)
{
// 机构会计日
// Date trfDate = orgAcctDayComponent.getTrfAcctDay().getStandardDate();
Loan
loan
=
loanAstAssembler
.
lockByAstNo
(
astNo
,
execDate
);
// 判断日期
if
(
DateTimeUtil
.
calcDayDiff
(
loan
.
getLastUpdateDate
(),
execDate
)
>
0
)
{
LogUtil
.
error
(
LOGGER
,
"[{0}]资金匹配失败,[{1}]资产更新日期[{2}]大于任务生成日期[{3}]"
,
planNo
,
loan
.
getAstNo
(),
loan
.
getLastUpdateDate
(),
execDate
);
return
false
;
}
// 判断是否全部转让
if
(
loan
.
getAstOrg
().
getAstOwnership
().
getOwnStatus
()
==
OwnStatusEnum
.
TRANS_OUT
)
{
LogUtil
.
info
(
LOGGER
,
"[{0}]资金匹配跳过,[{1}]资产已全部转让,可能存在转让任务,跳过该资产"
,
planNo
,
loan
.
getLastUpdateDate
(),
execDate
);
return
true
;
}
for
(
InvestStructure
investStructure
:
investStructureList
)
{
// 判断投资结构是否需要匹配
if
(
needMatchBalMap
.
get
(
investStructure
.
getLayerNo
())
==
null
)
{
continue
;
}
Money
needMatchBal
=
needMatchBalMap
.
get
(
investStructure
.
getLayerNo
());
if
(!
needMatchBal
.
isGreaterThanZero
())
{
continue
;
}
Map
<
String
,
String
>
extInf
=
loan
.
getExtInf
();
String
bfCapitalNo
=
extInf
.
get
(
LoanExtInfConstants
.
BF_CAPITAL_NO
);
if
(
StringUtils
.
isNotEmpty
(
bfCapitalNo
)
&&
StringUtils
.
equals
(
bfCapitalNo
,
investStructure
.
getLayerNo
()))
{
continue
;
}
// 资产到期日 小于等于 投资结构到期日
if
(
DateTimeUtil
.
calcDayDiff
(
investStructure
.
getLayerEndDate
(),
loan
.
getAstPeriod
().
getEndDate
())
>=
0
)
{
// 匹配成功
LoanAstGroup
loanAstGroup
=
loan
.
filterLoanAstByOrg
(
loan
.
getAstOrg
().
getAstOwnership
().
getLenderOrgCode
(),
loan
.
getTermCnt
());
Money
loanAstBal
=
new
Money
();
loanAstGroup
.
getLoanAsts
().
forEach
(
item
->
{
loanAstBal
.
addTo
(
item
.
getPrinBal
());
});
// 更新目标匹配余额
needMatchBal
.
subtractFrom
(
loanAstBal
);
String
batchNo
=
SequenceUtil
.
genId
(
CAP_AST_MATCH
);
String
timeStamp
=
TimeStampUtil
.
getDefaultTimeStamp
();
TransInfoTemplate
transInTemplate
=
new
TransInfoTemplate
();
transInTemplate
.
setTransTime
(
SystemDateUtil
.
getSystemDate
());
transInTemplate
.
setAccountDate
(
execDate
);
transInTemplate
.
setEventCode
(
EventCodeEnum
.
CAP_AST_MATCH
);
transInTemplate
.
setOutBizNo
(
batchNo
);
transInTemplate
.
setBizNo
(
SequenceUtil
.
genSeqNo
(
TransCodeEnum
.
CAP_AST_MATCH
));
transInTemplate
.
setTimestamp
(
timeStamp
);
// 构造交易详情
LoanTransDetail
loanTransDetail
=
LoanTransDetail
.
createLoanAstTxnDtl
(
loan
,
transInTemplate
);
// 更新资金编号
loanTransDetail
.
setCapitalInfo
(
investStructure
.
getLayerNo
(),
investStructure
.
getLayerName
());
loanTransDetail
.
processBeforeUpdate
();
// 更新信息
loanAstAssembler
.
store
(
loan
,
execDate
,
false
);
List
<
LoanBak
>
loanBaks
=
LoanTransDetail
.
buildBaks
(
loan
,
transInTemplate
.
getAccountDate
());
loanRepository
.
backup
(
loanBaks
);
return
true
;
}
}
return
false
;
}
/**
* 计算匹配余额
*
* @param investStructureList 投资结构列表
* @param astScaleSum 资产总规模
* @param astScaleMap 资产规模
* @param rateMap 资金比例
* @param investStructureBalSum 投资结构总余额
* @param planNo 计划编号
* @param balMap 投资结构资金余额
* @param removeIfNegtive 匹配余额小于等于0时是否移除 false 不移除 true 移除
* @return
*/
private
Map
<
String
,
Money
>
calcNeedMatchBal
(
List
<
InvestStructure
>
investStructureList
,
Money
astScaleSum
,
Map
<
String
,
Money
>
astScaleMap
,
Map
<
String
,
BigDecimal
>
rateMap
,
Money
investStructureBalSum
,
String
planNo
,
Map
<
String
,
Money
>
balMap
,
boolean
removeIfNegtive
)
{
Map
<
String
,
Money
>
needMatchBalMap
=
Maps
.
newHashMap
();
Iterator
<
InvestStructure
>
iterator
=
investStructureList
.
iterator
();
while
(
iterator
.
hasNext
())
{
InvestStructure
investStructure
=
iterator
.
next
();
if
(
balMap
.
get
(
investStructure
.
getLayerNo
())
==
null
)
{
continue
;
}
Money
needMatchBal
=
astScaleSum
.
multiply
(
rateMap
.
get
(
investStructure
.
getLayerNo
()));
Money
alreadyMatchMoney
=
astScaleMap
.
getOrDefault
(
investStructure
.
getLayerNo
(),
new
Money
());
// 判断目标匹配余额,这边会修改needMatchBal的值
needMatchBal
.
subtractFrom
(
alreadyMatchMoney
);
if
(!
needMatchBal
.
isGreaterThanZero
()
&&
removeIfNegtive
)
{
investStructureBalSum
.
subtractFrom
(
balMap
.
get
(
investStructure
.
getLayerNo
()));
balMap
.
remove
(
investStructure
.
getLayerNo
());
continue
;
}
needMatchBalMap
.
put
(
investStructure
.
getLayerNo
(),
needMatchBal
);
}
return
needMatchBalMap
;
}
/**
* 计算资金比例
*
* @param investStructureList 投资结构
* @param balMap 余额
* @param sum 总额
* @return
*/
private
Map
<
String
,
BigDecimal
>
calcCapistalRate
(
List
<
InvestStructure
>
investStructureList
,
Map
<
String
,
Money
>
balMap
,
Money
sum
,
String
planNo
)
{
// 非0保护
VarChecker
.
checkArgument
(
sum
.
isGreaterThanZero
(),
"[CapitalAstMatchHandler] - [{0}]投资结构总剩余规模为0"
,
planNo
);
Map
<
String
,
BigDecimal
>
rateMap
=
Maps
.
newHashMap
();
investStructureList
.
forEach
(
item
->
{
Money
bal
=
balMap
.
getOrDefault
(
item
.
getLayerNo
(),
new
Money
(
0
));
BigDecimal
rate
=
bal
.
getAmount
().
divide
(
sum
.
getAmount
(),
2
,
BigDecimal
.
ROUND_HALF_UP
);
rateMap
.
put
(
item
.
getLayerNo
(),
rate
);
});
return
rateMap
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/CapitalAstUnMatchHandler.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
import
com.abssqr.plat.common.dal.mysql.auto.paging.CapitalAstUnMatchPage
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.AstScale
;
import
com.abssqr.plat.common.facade.enums.*
;
import
com.abssqr.plat.common.facade.model.plan.InvestStructure
;
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.model.domain.ast.Loan
;
import
com.abssqr.plat.common.model.domain.ast.LoanAstGroup
;
import
com.abssqr.plat.common.model.domain.ast.LoanBak
;
import
com.abssqr.plat.common.model.domain.job.JobControl
;
import
com.abssqr.plat.common.model.domain.loanTrans.LoanTransDetail
;
import
com.abssqr.plat.common.model.domain.loanTrans.TransInfoTemplate
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.exception.AbssqrBizException
;
import
com.abssqr.plat.common.model.repo.ast.LoanBakRepo
;
import
com.abssqr.plat.common.model.repo.ast.LoanRepository
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
import
com.abssqr.plat.common.model.repo.loanTrans.LoanLogRepository
;
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.task.CommonTaskRepository
;
import
com.abssqr.plat.common.model.repo.tr.TrTaskRepo
;
import
com.abssqr.plat.common.model.seq.SequenceUtil
;
import
com.abssqr.plat.common.util.base.autoconfig.AbsConfig
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.ast.LoanAstAssembler
;
import
com.abssqr.plat.core.service.plan.PlanInvestStructureManager
;
import
com.abssqr.plat.core.service.system.TimeStampUtil
;
import
com.general.system.common.model.Money
;
import
com.general.system.common.util.*
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
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.math.BigDecimal
;
import
java.util.*
;
import
java.util.stream.Collectors
;
import
static
com
.
abssqr
.
plat
.
common
.
model
.
enums
.
IdTypeEnum
.
CAP_AST_UNMATCH
;
/**
* 资金资产解除绑定
*/
@Component
public
class
CapitalAstUnMatchHandler
{
private
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
getClass
());
@Autowired
private
TrTaskRepo
trTaskRepo
;
@Autowired
private
PlanInvestStructureManager
planInvestStructureManager
;
@Autowired
private
PlanAllocRepo
planAllocRepo
;
@Autowired
private
PlanAcctTitleRepo
planAcctTitleRepo
;
@Autowired
private
LoanBakRepo
loanBakRepo
;
@Autowired
LoanRepository
loanRepository
;
@Autowired
LoanLogRepository
loanLogRepository
;
@Autowired
private
TransactionTemplate
transactionTemplate
;
@Autowired
private
LoanAstAssembler
loanAstAssembler
;
@Autowired
private
CommonTaskRepository
commonTaskRepository
;
@Autowired
private
AbsConfig
absConfig
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
@Autowired
private
JobControlRepository
jobControlRepository
;
@Autowired
private
CapitalAssertMatchJob
capitalAssertMatchJob
;
private
int
queryLimit
=
2000
;
/**
*
* @param planNo
* @param allocNo
* @param acctDate
* @return
*/
public
boolean
execute
(
String
planNo
,
String
allocNo
,
Date
acctDate
){
//判断存在ignore、init、exec状态的转让任务
Long
cnt
=
trTaskRepo
.
cntTrTaskByTfrOut
(
planNo
,
Lists
.
newArrayList
(
TaskStatusEnum
.
IGNORE
.
getCode
(),
TaskStatusEnum
.
INIT
.
getCode
(),
TaskStatusEnum
.
EXECUTING
.
getCode
()),
AstPackTradeTypeEnum
.
AST_TRF_BIZ
);
VarChecker
.
checkArgument
(
cnt
.
intValue
()
==
0
,
"[CapitalAstUnMatchHandler] - [{0}]转让任务未完成"
,
planNo
);
LogUtil
.
info
(
LOGGER
,
"[CapitalAstUnMatchHandler] - [{0}]开始资金资产解绑兑付计划编号[{1}]"
,
planNo
,
allocNo
);
//获取该计划下的所有的科目信息
List
<
PlanAcctTitle
>
planAcctTitles
=
planAcctTitleRepo
.
getByEntityNo
(
planNo
);
//获取该计划下的所有投资结构编号
List
<
InvestStructure
>
investStructureList
=
planInvestStructureManager
.
selectByPlanNo
(
planNo
);
Set
<
String
>
allLayerNos
=
investStructureList
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
InvestStructure:
:
getLayerNo
))
.
keySet
();
//通过兑付计划获取兑付计划对应的投资层级编号
PlanAlloc
planAllocDetail
=
planAllocRepo
.
getPlanAllocDetail
(
allocNo
);
VarChecker
.
checkArgument
(
planAllocDetail
!=
null
,
"[CapitalAstUnMatchHandler] - [{0}]兑付单不存在"
,
allocNo
);
//投资科目编号
Set
<
String
>
titleNos
=
planAllocDetail
.
getPlanAllocItemList
().
stream
()
.
filter
(
v
->
v
.
getConfirmAmt
()!=
null
&&
v
.
getConfirmAmt
().
isGreaterThanZero
())
.
collect
(
Collectors
.
groupingBy
(
PlanAllocItem:
:
getTitleNo
))
.
keySet
();
//兑付单对应的投资层级编号
Set
<
String
>
allocLayerNos
=
planAcctTitles
.
stream
()
.
filter
(
v
->
titleNos
.
contains
(
v
.
getTitleNo
()))
.
collect
(
Collectors
.
groupingBy
(
PlanAcctTitle:
:
getRefNo
))
.
keySet
();
//计算各个投资层级需要解绑的资产额度
final
Map
<
String
,
Money
>
needUnMatchBalMap
=
caclNeedUnMatchCapitalBal
(
planNo
,
planAcctTitles
,
allLayerNos
,
allocLayerNos
,
acctDate
);
needUnMatchBalMap
.
forEach
((
layerNo
,
needUnMatchMoney
)->{
CapitalAstUnMatchPage
capitalAstMatchPage
=
new
CapitalAstUnMatchPage
();
capitalAstMatchPage
.
setCurrPageNo
(
1
);
capitalAstMatchPage
.
setLimit
(
queryLimit
);
capitalAstMatchPage
.
setCapitalNo
(
layerNo
);
do
{
boolean
b
=
unMatchCaptialAst
(
planNo
,
capitalAstMatchPage
,
needUnMatchMoney
,
acctDate
);
if
(!
b
)
{
break
;
}
}
while
(
capitalAstMatchPage
.
hasNextPage
());
});
;
//生成解绑重新匹配的Task
CommonTask
commonTask
=
buildUnMatchMatchTask
(
planNo
,
generateBizNo
(
CommonTaskTypeEnum
.
UNMATCH_CAPTITALASSERT_MATCH
,
planNo
,
acctDate
,
allocNo
));
commonTaskRepository
.
create
(
commonTask
);
return
true
;
}
/**
* 计算需要解绑的金额
* @param planNo 计划编号
* @param planAcctTitles 科目
* @param allLayerNos 所有的投资层级编号
* @param acctDate 会计日
* @param allocLayerNos 兑付计划对应的投资层级编号
* @return
*/
private
Map
<
String
,
Money
>
caclNeedUnMatchCapitalBal
(
String
planNo
,
List
<
PlanAcctTitle
>
planAcctTitles
,
Set
<
String
>
allLayerNos
,
Set
<
String
>
allocLayerNos
,
Date
acctDate
){
//获取已审批未兑付的金额
Map
<
String
,
Money
>
willPayMoneyMap
=
planAllocRepo
.
queryApprovedNotPayMoneyGroupByLayerNo
(
planNo
);
//计算所有投资结构持有的资金和资金总额
Money
investStructureBalSum
=
new
Money
();
Map
<
String
,
Money
>
balMap
=
calcCaptial
(
willPayMoneyMap
,
investStructureBalSum
,
planAcctTitles
);
if
(!(
allLayerNos
.
size
()
==
balMap
.
size
()))
{
LogUtil
.
error
(
LOGGER
,
"[CapitalAstMatchHandler] - [{0}]投资结构与本金科目不一致"
,
planNo
);
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"[{0}]投资结构与本金科目不一致"
,
planNo
),
CommonErrorCodeEnum
.
INVALID_PARAM
,
false
);
}
if
(!
investStructureBalSum
.
isGreaterThanZero
()){
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"投资结构资金小于0"
,
planNo
),
CommonErrorCodeEnum
.
INVALID_PARAM
,
false
);
}
// 计算资金比例
Map
<
String
,
BigDecimal
>
rateMap
=
this
.
calcCapistalRate
(
allLayerNos
,
balMap
,
investStructureBalSum
);
//计算获取信托资产规模
List
<
AstScale
>
astScaleList
=
loanBakRepo
.
getAstScale
(
acctDate
,
planNo
);
Money
astScaleSum
=
new
Money
();
Map
<
String
,
Money
>
astScaleMap
=
Maps
.
newHashMap
();
astScaleList
.
forEach
(
item
->
{
astScaleSum
.
addTo
(
item
.
getPrinBal
());
astScaleMap
.
put
(
item
.
getCapitalNo
(),
item
.
getPrinBal
());
});
// 计算目标匹配余额并移除变更金额<0且不为兑付对应投资结构的投资结构
calcUnMatchMatchBal
(
allLayerNos
,
astScaleMap
,
astScaleSum
,
rateMap
,
allocLayerNos
,
investStructureBalSum
,
balMap
);
//重新计算资金比
calcCapistalRate
(
allLayerNos
,
balMap
,
astScaleSum
);
//重新计算资产差额
Map
<
String
,
Money
>
allRebalanceBalMap
=
calcUnMatchMatchBal
(
allLayerNos
,
astScaleMap
,
astScaleSum
,
rateMap
,
allocLayerNos
,
investStructureBalSum
,
balMap
);
Map
<
String
,
Money
>
needUnbinBalMap
=
new
HashMap
<>();
allRebalanceBalMap
.
forEach
((
layerNo
,
unBindBal
)->{
if
(
allocLayerNos
.
contains
(
layerNo
)&&
unBindBal
.
isNegtive
()){
needUnbinBalMap
.
put
(
layerNo
,
unBindBal
);
}
});
return
needUnbinBalMap
;
}
/**
* 计算所有机构持有的资金
* @param willPayMoneyMap
* @param investStructureBalSum
* @param planAcctTitles
* @return
*/
private
Map
<
String
,
Money
>
calcCaptial
(
Map
<
String
,
Money
>
willPayMoneyMap
,
Money
investStructureBalSum
,
List
<
PlanAcctTitle
>
planAcctTitles
){
Map
<
String
,
Money
>
balMap
=
new
HashMap
<>();
for
(
PlanAcctTitle
planAcctTitle:
planAcctTitles
){
if
(
planAcctTitle
.
getTitleType
()
==
TitleTypeEnum
.
INVESTED
||
planAcctTitle
.
getTitleType
()
==
TitleTypeEnum
.
PRIOR_INVESTED
||
planAcctTitle
.
getTitleType
()
==
TitleTypeEnum
.
SECND_INVESTED
)
{
Money
money
=
planAcctTitle
.
getBal
().
clone
();
Money
willPayMoney
=
willPayMoneyMap
.
getOrDefault
(
planAcctTitle
.
getRefNo
(),
new
Money
());
money
.
subtractFrom
(
willPayMoney
);
balMap
.
put
(
planAcctTitle
.
getRefNo
(),
money
);
investStructureBalSum
.
addTo
(
money
);
}
}
return
balMap
;
}
/**
* 计算资金比例
*
* @param layerNos 投资结构编号
* @param balMap 余额
* @param sum 总额
* @return
*/
private
Map
<
String
,
BigDecimal
>
calcCapistalRate
(
Set
<
String
>
layerNos
,
Map
<
String
,
Money
>
balMap
,
Money
sum
)
{
Map
<
String
,
BigDecimal
>
rateMap
=
Maps
.
newHashMap
();
layerNos
.
forEach
(
item
->
{
Money
bal
=
balMap
.
get
(
item
);
BigDecimal
rate
=
bal
.
getAmount
().
divide
(
sum
.
getAmount
(),
2
,
BigDecimal
.
ROUND_HALF_UP
);
rateMap
.
put
(
item
,
rate
);
});
return
rateMap
;
}
/**
* 计算资金资产差额
* @param allLayerNos 所有的投资层级编号
* @param astScaleMap 各投资结构的资产规模
* @param astScaleSum 所有投资结构的资产总额
* @param rateMap 各投资结构的资金比例
* @param allocLayerNos 兑付计划对应的投资层级编号
* @param investStructureBalSum 投资层级资金总额度
* @param balMap 各投资层级对应的资金
* @return
*/
private
Map
<
String
,
Money
>
calcUnMatchMatchBal
(
Set
<
String
>
allLayerNos
,
Map
<
String
,
Money
>
astScaleMap
,
Money
astScaleSum
,
Map
<
String
,
BigDecimal
>
rateMap
,
Set
<
String
>
allocLayerNos
,
Money
investStructureBalSum
,
Map
<
String
,
Money
>
balMap
){
Map
<
String
,
Money
>
needUnMatchBalMap
=
new
HashMap
<>();
Iterator
<
String
>
iterator
=
allLayerNos
.
iterator
();
while
(
iterator
.
hasNext
()){
String
layerNo
=
iterator
.
next
();
BigDecimal
balRate
=
rateMap
.
get
(
layerNo
);
//目标兑付资产
Money
targetBal
=
astScaleSum
.
multiply
(
balRate
);
//持有的资产
Money
matchedBal
=
astScaleMap
.
getOrDefault
(
layerNo
,
new
Money
());
//资产差额(目标兑付的资产-持有资产)
Money
divide
=
targetBal
.
subtract
(
matchedBal
);
//资产差额是负的且不属于兑付计划的移除
if
(
divide
.
isNegtive
()&&!
allocLayerNos
.
contains
(
layerNo
)){
investStructureBalSum
.
subtractFrom
(
balMap
.
get
(
layerNo
));
balMap
.
remove
(
layerNo
);
iterator
.
remove
();
continue
;
}
needUnMatchBalMap
.
put
(
layerNo
,
divide
);
}
return
needUnMatchBalMap
;
}
/**
* 进行解绑操作
* @param capitalAstUnMatchPage
* @param needUnMatchBal
* @param acctDate
* @return
*/
private
boolean
unMatchCaptialAst
(
String
planNo
,
CapitalAstUnMatchPage
capitalAstUnMatchPage
,
Money
needUnMatchBal
,
Date
acctDate
){
boolean
match
=
true
;
//增加Job控制
JobControl
jobControl
=
jobControlRepository
.
selectByJobName
(
capitalAssertMatchJob
.
getJobName
());
if
(
jobControl
.
getIsEff
()==
YNEnum
.
N
){
LogUtil
.
error
(
LOGGER
,
"计划[{0}]解绑失败,资金资产匹配任务运行中被关闭"
,
planNo
);
return
false
;
}
capitalAstUnMatchPage
=
loanRepository
.
queryForCapitalAstUnMatch
(
capitalAstUnMatchPage
);
List
<
String
>
astNoList
=
capitalAstUnMatchPage
.
getDatas
();
for
(
String
astNo
:
astNoList
)
{
match
=
transactionTemplate
.
execute
(
status
->
{
//判断资金是否为负
if
(
needUnMatchBal
.
isGreaterThanZero
()){
return
false
;
}
Loan
loan
=
loanAstAssembler
.
lockByAstNo
(
astNo
,
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
());
// 判断是否全部转让
if
(
loan
.
getAstOrg
().
getAstOwnership
().
getOwnStatus
()
==
OwnStatusEnum
.
TRANS_OUT
)
{
LogUtil
.
info
(
LOGGER
,
"[{0}]资产解绑跳过,[{1}]资产已全部转让,可能存在转让任务,跳过该资产"
,
astNo
,
loan
.
getLastUpdateDate
(),
acctDate
);
return
false
;
}
return
this
.
unMatchCaptical
(
loan
,
needUnMatchBal
,
acctDate
);
});
if
(!
match
){
break
;
}
}
return
match
;
}
/**
* 进行解绑操作
* @param loan
* @param needUnMatchBal
* @param acctDate
* @return
*/
private
boolean
unMatchCaptical
(
Loan
loan
,
Money
needUnMatchBal
,
Date
acctDate
){
LoanAstGroup
loanAstGroup
=
loan
.
filterLoanAstByOrg
(
loan
.
getAstOrg
().
getAstOwnership
().
getLenderOrgCode
(),
loan
.
getTermCnt
());
//计算资产额度
Money
loanAstBal
=
new
Money
();
loanAstGroup
.
getLoanAsts
().
forEach
(
item
->
{
loanAstBal
.
addTo
(
item
.
getPrinBal
());
});
// 更新目标匹配余额
needUnMatchBal
.
addTo
(
loanAstBal
);
//创建交易详情
String
batchNo
=
SequenceUtil
.
genId
(
CAP_AST_UNMATCH
);
String
timeStamp
=
TimeStampUtil
.
getDefaultTimeStamp
();
TransInfoTemplate
transInTemplate
=
new
TransInfoTemplate
();
transInTemplate
.
setTransTime
(
SystemDateUtil
.
getSystemDate
());
transInTemplate
.
setAccountDate
(
acctDate
);
transInTemplate
.
setEventCode
(
EventCodeEnum
.
CAP_AST_UNMATCH
);
transInTemplate
.
setOutBizNo
(
batchNo
);
transInTemplate
.
setBizNo
(
SequenceUtil
.
genSeqNo
(
TransCodeEnum
.
CAP_AST_UNMATCH
));
transInTemplate
.
setTimestamp
(
timeStamp
);
// 构造交易详情
LoanTransDetail
loanTransDetail
=
LoanTransDetail
.
createLoanAstTxnDtl
(
loan
,
transInTemplate
);
// 更新资金编号
loanTransDetail
.
setCapitalInfo
(
CapitalAstMatchEnum
.
DEFAULT
.
getCode
(),
null
);
loanTransDetail
.
processBeforeUpdate
();
// 更新信息
loanAstAssembler
.
store
(
loan
,
acctDate
,
false
);
List
<
LoanBak
>
loanBaks
=
LoanTransDetail
.
buildBaks
(
loan
,
transInTemplate
.
getAccountDate
());
loanRepository
.
backup
(
loanBaks
);
return
true
;
}
private
CommonTask
buildUnMatchMatchTask
(
String
planNo
,
String
bizNo
){
CommonTask
commonTask
=
new
CommonTask
();
commonTask
.
setContext
(
planNo
);
commonTask
.
setTaskStatus
(
TaskStatusEnum
.
IGNORE
);
commonTask
.
setTaskType
(
CommonTaskTypeEnum
.
UNMATCH_CAPTITALASSERT_MATCH
);
commonTask
.
setEnv
(
absConfig
.
getEnv
());
commonTask
.
setBizNo
(
bizNo
);
commonTask
.
setExecTimes
(
0L
);
return
commonTask
;
}
//生成解绑匹配业务码
private
static
String
generateBizNo
(
CommonTaskTypeEnum
commonTaskTypeEnum
,
String
planNo
,
Date
accountDate
,
String
allocNo
){
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
commonTaskTypeEnum
.
getCode
());
sb
.
append
(
"-"
);
sb
.
append
(
planNo
);
sb
.
append
(
"-"
);
sb
.
append
(
DateTimeUtil
.
formatYMD
(
accountDate
));
sb
.
append
(
"-"
);
sb
.
append
(
allocNo
);
return
sb
.
toString
();
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/FinSerFeeHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
/**
*
* @author hanfei
* @version $Id: FinSerFeeHandler.java, v 0.1 2020-03-09 2:01 PM hanfei Exp $
*/
public
class
FinSerFeeHandler
{
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/LoanAstBuyBackHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
com.abssqr.plat.common.facade.enums.AstPackTradeTypeEnum
;
import
com.abssqr.plat.common.model.domain.ast.Loan
;
import
com.abssqr.plat.common.model.domain.ast.LoanAstBuyBackPack
;
import
com.abssqr.plat.common.model.domain.task.TrTask
;
import
com.abssqr.plat.common.model.domain.trade.AstTradeParam
;
import
com.abssqr.plat.common.util.profiler.PerformTrace
;
import
com.abssqr.plat.core.service.ast.LoanAstAssembler
;
import
com.abssqr.plat.core.service.ast.LoanAstBuyBackManager
;
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.Component
;
/**
* 回购转让交易执行处理器
* @author hanfei
* @version $Id: LoanAstBuyBackHandler.java, v 0.1 2020-02-11 5:15 PM hanfei Exp $
*/
@Component
public
class
LoanAstBuyBackHandler
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
LoanAstBuyBackHandler
.
class
);
@Autowired
private
LoanAstAssembler
loanAstAssembler
;
@Autowired
private
LoanAstBuyBackManager
loanAstBuyBackManager
;
/**
*
* @param trTask
* @return
*/
@PerformTrace
public
boolean
astBuyBackExecute
(
TrTask
trTask
)
{
// 1 捞取加锁loan资产
Loan
loan
=
loanAstAssembler
.
lockByAstNo
(
trTask
.
getAstNo
(),
trTask
.
getTfrDt
());
if
(
loan
==
null
)
{
LogUtil
.
warn
(
LOGGER
,
"[astBuyBackExecute][{0}]捞不到待转借据"
,
trTask
.
getAstNo
());
return
false
;
}
// 查询资产包
LoanAstBuyBackPack
pack
=
loanAstBuyBackManager
.
getByPackCode
(
trTask
.
getTfrPack
());
VarChecker
.
checkNotNull
(
pack
,
"[astBuyBackExecute]-资产回购交易失败,没有对应的Pack"
);
AstTradeParam
astTrade
=
new
AstTradeParam
();
astTrade
.
setPack
(
pack
);
astTrade
.
setLoan
(
loan
);
astTrade
.
setAstTradeType
(
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
// 11 成功回购后,回购资产任务更新TASK_STATUS为success
return
loanAstBuyBackManager
.
astBuyBackTrade
(
trTask
,
astTrade
);
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/LoanAstBuyBackMatchHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
com.abssqr.plat.biz.shared.dispatcher.buyBackMatch.LoanAstBuyBackMatchStarter
;
import
com.abssqr.plat.common.dal.mysql.auto.dataobject.LoanBakDO
;
import
com.abssqr.plat.common.dal.mysql.auto.paging.LoanBakListPage
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.AstPoolItem
;
import
com.abssqr.plat.common.facade.enums.*
;
import
com.abssqr.plat.common.facade.model.org.OrganizationEntity
;
import
com.abssqr.plat.common.facade.model.plan.Plan
;
import
com.abssqr.plat.common.facade.model.plan.PlanBase
;
import
com.abssqr.plat.common.facade.model.rule.AstPriceRule
;
import
com.abssqr.plat.common.facade.model.rule.AstScreenRule
;
import
com.abssqr.plat.common.facade.model.rule.TradePriceRule
;
import
com.abssqr.plat.common.model.domain.ast.*
;
import
com.abssqr.plat.common.model.domain.contract.LoanContract
;
import
com.abssqr.plat.common.model.domain.job.JobControl
;
import
com.abssqr.plat.common.model.domain.rule.LoanAstPriceCalcParam
;
import
com.abssqr.plat.common.model.domain.rule.LoanAstPriceResult
;
import
com.abssqr.plat.common.model.domain.task.TrCtrTask
;
import
com.abssqr.plat.common.model.domain.task.TrTask
;
import
com.abssqr.plat.common.model.enums.IdTypeEnum
;
import
com.abssqr.plat.common.model.repo.ast.LoanRepository
;
import
com.abssqr.plat.common.model.repo.ast.PackRepository
;
import
com.abssqr.plat.common.model.repo.contract.LoanContractRepository
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
import
com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo
;
import
com.abssqr.plat.common.model.repo.tr.TrCtrTaskRepo
;
import
com.abssqr.plat.common.model.repo.tr.TrTaskRepo
;
import
com.abssqr.plat.common.model.seq.SequenceUtil
;
import
com.abssqr.plat.common.model.utils.TextUtil
;
import
com.abssqr.plat.common.util.profiler.PerformTrace
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.ast.LoanAstAssembler
;
import
com.abssqr.plat.core.service.ast.LoanAstBuyBackManager
;
import
com.abssqr.plat.core.service.plan.PlanManager
;
import
com.abssqr.plat.core.service.rule.AstPriceRuleComponent
;
import
com.abssqr.plat.core.service.rule.AstScreenRuleComponent
;
import
com.general.system.common.util.*
;
import
com.general.system.tool.util.ToolUtil
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
org.apache.commons.collections.CollectionUtils
;
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.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Optional
;
import
java.util.function.Consumer
;
import
static
com
.
abssqr
.
plat
.
common
.
model
.
enums
.
IdTypeEnum
.
ASTSCREENINGRULE
;
/**
* 回购
*
* @author xiachenxiang
* @version com.abssqr.plat.biz.shared.handler: LoanAstBuyBackMatchHandler.java, v 0.1 2020-02-10 1:50 PM xiachenxiang Exp $
*/
@Component
public
class
LoanAstBuyBackMatchHandler
{
private
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
getClass
());
@Autowired
private
TrTaskRepo
trTaskRepo
;
@Autowired
private
PackRepository
packRepository
;
@Autowired
private
LoanAstBuyBackManager
loanAstBuyBackManager
;
@Autowired
private
AstSyncTaskCtrRepo
astSyncTaskCtrRepo
;
@Autowired
private
LoanRepository
loanRepository
;
@Autowired
private
LoanContractRepository
loanContractRepository
;
@Autowired
private
TrCtrTaskRepo
trCtrTaskRepo
;
@Autowired
private
AstScreenRuleComponent
astScreenRuleComponent
;
@Autowired
private
TransactionTemplate
transactionTemplate
;
@Autowired
private
AstPriceRuleComponent
astPriceRuleComponent
;
@Autowired
private
LoanAstAssembler
loanAstAssembler
;
@Autowired
private
JobControlRepository
jobControlRepository
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
@Autowired
private
PlanManager
planManager
;
private
final
int
limit
=
2000
;
private
int
batchInsertCnt
=
500
;
@PerformTrace
(
name
=
"LoanAstBuyBackMatchHandler"
)
public
void
execute
(
String
packCode
,
Consumer
<
TaskStatusEnum
>
consumer
)
{
// 1.获取资产包
LoanAstBuyBackPack
existPack
=
loanAstBuyBackManager
.
getByPackCode
(
packCode
);
VarChecker
.
checkNotNull
(
existPack
,
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,没有对应的Pack"
);
// 2.判断状态
VarChecker
.
checkEquals
(
existPack
.
getPackStatus
(),
AstPackStatusEnum
.
INIT
,
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,Pack[{0}]的状态不为init"
,
existPack
.
getPackCode
());
// 3.清理历史TrTask
Date
curDate
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
trTaskRepo
.
clearHisTrTask
(
existPack
.
getBackOutCode
(),
curDate
,
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
Map
<
String
,
TrCtrTask
>
trCtrTaskMap
=
Maps
.
newHashMap
();
String
batchNo
=
SequenceUtil
.
genId
(
ASTSCREENINGRULE
);
LogUtil
.
info
(
LOGGER
,
"开始筛选[{0}]受让计划,批次号=[{1}]"
,
existPack
.
getBackOutCode
(),
batchNo
);
// 校验是否完成模型同步
this
.
checkAstModFinished
(
existPack
,
curDate
);
// 4.分页遍历承接池机构资产
LoanBakListPage
page
=
new
LoanBakListPage
();
page
.
setAccountDate
(
curDate
);
page
.
setOwnOrg
(
existPack
.
getBackOutCode
());
page
.
setStatuList
(
Lists
.
newArrayList
(
LoanStatusEnum
.
NORMAL
.
getCode
(),
LoanStatusEnum
.
OVERDUE
.
getCode
()));
page
.
setLimit
(
limit
);
page
.
setCurrPageNo
(
1
);
do
{
if
(!
this
.
canRun
())
{
LogUtil
.
info
(
LOGGER
,
"[LoanAstBuyBackMatchHandler] - 检测到[{0}]任务已停止,跳出筛选"
,
LoanAstBuyBackMatchStarter
.
JOB_NAME
);
break
;
}
LogUtil
.
info
(
LOGGER
,
"[LoanAstBuyBackMatchHandler]-[{0}]开始筛选[{0}]受让计划第[{1}]页"
,
existPack
.
getBackOutCode
(),
page
.
getCurrentPage
());
this
.
astMatch
(
page
,
existPack
,
trCtrTaskMap
,
curDate
,
batchNo
);
page
.
setCurrPageNo
(
page
.
getCurrPageNo
()
+
1
);
}
while
(
page
.
hasNextPage
());
LogUtil
.
info
(
LOGGER
,
"[LoanAstBuyBackMatchHandler] - 筛选结束"
);
// 5 更新转让数据状态
transactionTemplate
.
execute
(
status
->
{
packRepository
.
updatePackStatus
(
Lists
.
newArrayList
(
existPack
),
AstPackStatusEnum
.
SCEEN_FIS
,
AstPackStatusEnum
.
INIT
);
trTaskRepo
.
updateStatus
(
batchNo
,
TaskStatusEnum
.
INIT
,
TaskStatusEnum
.
IGNORE
);
//插入转让控制表,可以开始转让
if
(
ToolUtil
.
isNotEmpty
(
trCtrTaskMap
))
{
trCtrTaskRepo
.
insertBatch
(
Lists
.
newArrayList
(
trCtrTaskMap
.
values
()));
}
consumer
.
accept
(
TaskStatusEnum
.
SUCCESS
);
return
status
;
});
}
/**
* 判断当前机构是否完成模型同步
*
* @param pack 资产包
* @param curDate 会计日
*/
private
void
checkAstModFinished
(
LoanAstBuyBackPack
pack
,
Date
curDate
)
{
// 判断当日模型同步情况
List
<
String
>
orgCodes
=
astSyncTaskCtrRepo
.
getLastStatusFinishedOrgCodes
(
curDate
,
SyncTaskTypeEnum
.
AST_MOD
);
VarChecker
.
checkNotEmpty
(
orgCodes
,
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,当日没有机构完成模型同步"
);
// 判断当前转让会计日是否完成模型转换,未完成直接退出
PlanBase
buybackPlan
=
planManager
.
getPlanFullByNo
(
pack
.
getPlanNo
());
String
OrgCode
=
null
;
// 放款池回购受让池
if
(
buybackPlan
.
getPlanType
()
==
PlanTypeEnum
.
SPV
&&
buybackPlan
instanceof
OrganizationEntity
)
{
OrgCode
=
((
OrganizationEntity
)
buybackPlan
).
getManagerOrgCode
();
}
else
{
// 受让池回购受让池
// 判断两受让池对应的放款池是否一致
PlanBase
outplan
=
planManager
.
getPlanFullByNo
(
pack
.
getBackOutCode
());
VarChecker
.
checkArgument
(
outplan
.
getPlanType
()
==
PlanTypeEnum
.
PLAN
&&
outplan
instanceof
Plan
,
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,不支持的回购类型受让池回购放款池"
);
Optional
<
AstScreenRule
>
outTrfScreenRuleOptional
=
((
Plan
)
outplan
).
getPlanTransferRule
().
getAstScreenRuleList
().
stream
().
filter
(
item
->
item
.
getScreenType
()
==
ScreenTypeEnum
.
AST_TRF
).
findFirst
();
VarChecker
.
checkArgument
(
outTrfScreenRuleOptional
.
isPresent
(),
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,转让筛选规则不存在"
);
AstScreenRule
astScreenRule
=
outTrfScreenRuleOptional
.
get
();
VarChecker
.
checkEquals
(
astScreenRule
.
getLenderOrgCode
(),
pack
.
getLoanProduct
().
getLenderOrgCode
(),
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,两个受让计划不属于同一个放款池"
);
OrgCode
=
astScreenRule
.
getManagerOrgCode
();
}
VarChecker
.
checkArgument
(
orgCodes
.
contains
(
OrgCode
),
"[LoanAstBuyBackMatchHandler]-回购筛选启动失败,机构[{0}]未完成模型同步"
,
((
OrganizationEntity
)
buybackPlan
).
getManagerOrgCode
());
}
/**
* 检测是否继续执行筛选
*
* @return
*/
public
boolean
canRun
()
{
JobControl
jobControl
=
jobControlRepository
.
selectByJobName
(
LoanAstBuyBackMatchStarter
.
JOB_NAME
);
return
jobControl
.
getIsEff
().
isYes
();
}
private
void
astMatch
(
LoanBakListPage
page
,
LoanAstBuyBackPack
pack
,
Map
<
String
,
TrCtrTask
>
trCtrTaskMap
,
Date
curDate
,
String
batchNo
)
{
page
=
loanRepository
.
getPageByOwnOrg
(
page
);
List
<
LoanBakDO
>
datas
=
page
.
getDatas
();
List
<
TrTask
>
trTasks
=
Lists
.
newArrayList
();
for
(
LoanBakDO
loanBakDO
:
datas
)
{
// 5.1.根据筛选规则进行匹配
TrTask
trTask
=
null
;
boolean
isMatch
=
astScreenRuleComponent
.
astBuybackScreen
(
curDate
,
pack
,
()
->
buildAstPoolItem
(
curDate
,
loanBakDO
));
if
(
isMatch
)
{
// 5.2.匹配成功资产按照定价规则进行定价
LoanAstPriceResult
result
=
this
.
makePrice
(
loanBakDO
.
getAstNo
(),
pack
);
if
(
result
==
null
)
{
LogUtil
.
info
(
LOGGER
,
"[LoanAstBuyBackMatchHandler] - 计划[{0}]下机构资产[{1}]为0,跳过"
,
loanBakDO
.
getOwnOrg
(),
loanBakDO
.
getAstNo
());
continue
;
}
TrCtrTask
trCtrTask
=
trCtrTaskMap
.
get
(
pack
.
getPackCode
());
if
(
trCtrTask
==
null
)
{
trCtrTask
=
new
TrCtrTask
();
trCtrTaskMap
.
put
(
pack
.
getPackCode
(),
trCtrTask
);
trCtrTask
.
setTfrDate
(
curDate
);
trCtrTask
.
setBatchNo
(
batchNo
);
trCtrTask
.
setPackCode
(
pack
.
getPackCode
());
trCtrTask
.
setPackType
(
pack
.
getPackType
());
trCtrTask
.
setTaskStatus
(
TaskStatusEnum
.
INIT
);
trCtrTask
.
setManagerOrgCode
(
pack
.
getManagerOrgCode
());
trCtrTask
.
setPackType
(
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
}
if
(
MoneyUtil
.
compare
(
trCtrTask
.
getPreTrAmt
().
add
(
result
.
getPrice
().
getSum
()),
pack
.
getAvalAmt
())
<=
0
)
{
trCtrTask
.
addPreTrAmt
(
result
.
getPrice
().
getSum
());
trTask
=
dealTrTask
(
loanBakDO
,
batchNo
,
curDate
,
pack
,
result
);
}
}
if
(
trTask
!=
null
)
{
VarChecker
.
checkArgument
(
trTask
.
getTfrPrinBal
().
isGreaterThanZero
(),
"Pack筛选到资产-待转金额为0,trTask[{0}]"
,
trTask
);
trTasks
.
add
(
trTask
);
LogUtil
.
info
(
LOGGER
,
"[{0}]Pack筛选到资产,astNo=[{1}],batchNo=[{2}]"
,
trTask
.
getTfrPack
(),
trTask
.
getAstNo
(),
batchNo
);
trySaveTrTask
(
trTasks
,
batchInsertCnt
);
}
}
trySaveTrTask
(
trTasks
,
0
);
}
/**
* 计算定价
*
* @param astNo 资产编号
* @param pack 回购资产包
* @return
*/
private
LoanAstPriceResult
makePrice
(
String
astNo
,
LoanAstBuyBackPack
pack
)
{
Loan
loan
=
loanRepository
.
getByAstNo
(
astNo
);
loan
=
loanAstAssembler
.
assembleLoan
(
loan
,
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
());
LoanAstGroup
loanAstGroup
=
loan
.
filterLoanAstByOrg
(
pack
.
getBackOutCode
(),
loan
.
getTermCnt
());
LoanAstPriceResult
result
=
null
;
for
(
LoanAst
loanAst
:
loanAstGroup
.
getLoanAsts
())
{
LoanAstPriceCalcParam
param
=
new
LoanAstPriceCalcParam
();
param
.
setTransIn
(
pack
.
getPlanNo
());
param
.
setTransOut
(
pack
.
getBackOutCode
());
param
.
setLoanAst
(
loanAst
);
param
.
setTradePriceRules
(
pack
.
getAstPriceRuleList
());
param
.
setAstTradeType
(
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
// 资产五级分类
param
.
setCondition
(
loan
.
getLoanRisk
().
getRiskClass
().
getCode
());
if
(
null
==
result
)
{
result
=
astPriceRuleComponent
.
execute
(
param
);
}
else
{
result
.
merge
(
astPriceRuleComponent
.
execute
(
param
));
}
}
return
result
;
}
/**
* 尝试保存
*
* @param trTasks
* @param minSize
*/
private
void
trySaveTrTask
(
List
<
TrTask
>
trTasks
,
int
minSize
)
{
if
(
CollectionUtils
.
isNotEmpty
(
trTasks
)
&&
trTasks
.
size
()
>=
minSize
)
{
LogUtil
.
info
(
LOGGER
,
"LoanAstBuyBackMatchHandler 回购TrTask入库size={0},minSize={1}"
,
trTasks
.
size
(),
minSize
);
trTaskRepo
.
insertBatch
(
trTasks
);
trTasks
.
clear
();
}
}
private
TrTask
dealTrTask
(
LoanBakDO
loanBakDO
,
String
batchNo
,
Date
acctDate
,
LoanAstBuyBackPack
pack
,
LoanAstPriceResult
result
)
{
TrTask
task
=
new
TrTask
();
task
.
setExecTimes
(
0L
);
task
.
setTfrDt
(
acctDate
);
task
.
setBatchNo
(
batchNo
);
task
.
setNextExecTime
(
SystemDateUtil
.
getSystemDate
());
task
.
setAstNo
(
loanBakDO
.
getAstNo
());
task
.
setTfrPack
(
pack
.
getPackCode
());
task
.
setTermNo
(
loanBakDO
.
getTermCnt
());
task
.
setAstDueDt
(
loanBakDO
.
getEndDate
());
task
.
setTfrPrinBal
(
result
.
getBal
().
getAllPrin
());
task
.
setTaskStatus
(
TaskStatusEnum
.
IGNORE
);
task
.
setTfrOut
(
loanBakDO
.
getOwnOrg
());
task
.
setSeqNo
(
SequenceUtil
.
genId
(
IdTypeEnum
.
SEQ
));
task
.
setPackType
(
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
TradePriceRule
tradePriceRule
=
result
.
getTradePriceRule
();
VarChecker
.
checkArgument
(
tradePriceRule
instanceof
AstPriceRule
,
"[{0}]回购筛选交易定价类型有误"
,
pack
.
getBackOutCode
());
AstPriceRule
astPriceRule
=
(
AstPriceRule
)
tradePriceRule
;
task
.
setTfrIntrBal
(
result
.
getBal
().
getAllIntr
());
task
.
setTfrPenalFeeBal
(
result
.
getBal
().
getAllIntAndFee
().
subtract
(
result
.
getBal
().
getAllIntr
()));
task
.
setRiskCl
(
astPriceRule
.
getRiskCl
());
task
.
setIntrRate
(
astPriceRule
.
getIntrRate
());
task
.
setPrinRate
(
astPriceRule
.
getPrinRate
());
task
.
setPenalFeeRate
(
astPriceRule
.
getPenalFeeRate
());
task
.
setTfrAmt
(
result
.
getPrice
().
getSum
());
return
task
;
}
/**
* 构建资产条目
*
* @param curDate
* @param loanBakDO
* @return
*/
private
AstPoolItem
buildAstPoolItem
(
Date
curDate
,
LoanBakDO
loanBakDO
)
{
LoanContract
contract
=
loanContractRepository
.
getByAstNo
(
loanBakDO
.
getAstNo
());
// 需要
AstPoolItem
astPoolItem
=
new
AstPoolItem
();
astPoolItem
.
setStatus
(
loanBakDO
.
getStatus
());
astPoolItem
.
setAstNo
(
loanBakDO
.
getAstNo
());
astPoolItem
.
setProdNo
(
loanBakDO
.
getProdNo
());
astPoolItem
.
setTermNo
(
loanBakDO
.
getTermCnt
());
astPoolItem
.
setStartDate
(
loanBakDO
.
getStartDate
());
astPoolItem
.
setEndDate
(
loanBakDO
.
getEndDate
());
astPoolItem
.
setRemainDays
((
int
)
DateTimeUtil
.
calcDayDiff
(
astPoolItem
.
getEndDate
(),
curDate
));
astPoolItem
.
setPrinBal
(
loanBakDO
.
getPrinBal
());
//astPoolItem.setIntrBal(loan.getBal().getAllIntr());
//astPoolItem.setPrinPenalBal(loan.getBal().getByFieldType(DebtMoneyFieldEnum.PRIN_ODUE_PNY));
//astPoolItem.setIntrPenalBal(loan.getBal().getByFieldType(DebtMoneyFieldEnum.INTR_ODUE_PNY));
astPoolItem
.
setManagerOrgCode
(
loanBakDO
.
getManagerOrgCode
());
astPoolItem
.
setLenderOrgCode
(
loanBakDO
.
getLenderOrgCode
());
astPoolItem
.
setTermCnt
(
loanBakDO
.
getTermCnt
());
astPoolItem
.
setRiskCl
(
loanBakDO
.
getRiskCl
());
Map
<
String
,
String
>
context
=
Maps
.
newHashMap
();
context
.
put
(
AstConditions
.
CERT_NO
,
contract
.
getLoanCustInfo
().
getCertNo
());
context
.
put
(
AstConditions
.
CERT_TYPE
,
contract
.
getLoanCustInfo
().
getCertType
().
getCode
());
context
.
put
(
AstConditions
.
INTER_RATE
,
contract
.
getLoanProperty
().
getRate
().
toString
());
context
.
put
(
AstConditions
.
RATE_TYPE
,
contract
.
getLoanProperty
().
getRateType
().
getCode
());
astPoolItem
.
setContext
(
TextUtil
.
convertMap2Txt
(
context
));
return
astPoolItem
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/PlanAstReqHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
com.abssqr.plat.common.facade.enums.AstPackStatusEnum
;
import
com.abssqr.plat.common.facade.enums.TrCycleEnum
;
import
com.abssqr.plat.common.facade.enums.TransCodeEnum
;
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.PlanTransferRule
;
import
com.abssqr.plat.common.facade.model.rule.AstScreenRule
;
import
com.abssqr.plat.common.model.domain.ast.Pack
;
import
com.abssqr.plat.common.model.repo.clearing.PlanClearingLogRepo
;
import
com.abssqr.plat.common.model.repo.plan.PlanAstRepository
;
import
com.abssqr.plat.common.model.seq.SequenceUtil
;
import
com.abssqr.plat.core.service.ast.AstPackManager
;
import
com.abssqr.plat.core.service.plan.PlanInvestStructureManager
;
import
com.abssqr.plat.core.service.util.RptBuilderUtil
;
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
com.general.system.common.util.VarChecker
;
import
org.apache.commons.collections.CollectionUtils
;
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.handler: PlanAstReqHandler.java, v 0.1 2019-06-19 01:34 zhenxuan.luo Exp $
*/
@Component
public
class
PlanAstReqHandler
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanAstReqHandler
.
class
);
@Autowired
private
PlanAstRepository
planAstRepository
;
@Autowired
private
AstPackManager
astPackManager
;
@Autowired
private
PlanClearingLogRepo
planClearingLogRepo
;
@Autowired
private
PlanInvestStructureManager
planInvestStructureManager
;
public
Pack
execute
(
PlanBase
planBase
,
PlanTransferRule
transferRule
,
Date
accountDate
)
{
Date
tfrClearingDate
=
planClearingLogRepo
.
getMinUnStateAccountDate
(
planBase
.
getPlanNo
(),
null
);
if
(
tfrClearingDate
!=
null
)
{
LogUtil
.
info
(
LOGGER
,
"计划[{0}]创建资产包, 在[{1}]有未完成的转让任务待清算悬挂"
,
planBase
.
getPlanNo
(),
tfrClearingDate
);
return
null
;
}
VarChecker
.
checkNotNull
(
transferRule
,
"计划[{0}]创建资产包找不到对应转让规则"
,
planBase
.
getPlanNo
());
PlanAst
planAst
=
planAstRepository
.
getByPlanNo
(
planBase
.
getPlanNo
());
Pack
pack
=
new
Pack
();
pack
.
setPlanNo
(
planBase
.
getPlanNo
());
pack
.
setPackCode
(
SequenceUtil
.
genSeqNo
(
TransCodeEnum
.
OTHER
.
getCode
()));
pack
.
setPackName
(
MessageUtil
.
formatMsg
(
"{0}-{1}资产包"
,
planBase
.
getPlanName
(),
DateTimeUtil
.
formatYMD
(
accountDate
)));
pack
.
setTransferRule
(
transferRule
);
pack
.
setPackStatus
(
AstPackStatusEnum
.
INIT
);
pack
.
setScenDate
(
accountDate
);
pack
.
setMinEndDate
(
null
);
pack
.
setMaxEndDate
(
planBase
.
getEndDate
());
pack
.
setCalcIntrType
(
planBase
.
getCalcIntrType
());
if
(
CollectionUtils
.
isNotEmpty
(
transferRule
.
getAstScreenRuleList
()))
{
AstScreenRule
astScreenRule
=
transferRule
.
getAstScreenRuleList
().
stream
().
findFirst
().
get
();
pack
.
setManagerOrgCode
(
astScreenRule
.
getManagerOrgCode
());
}
boolean
isNeedPack
;
if
(
transferRule
.
getTrCycle
()
!=
TrCycleEnum
.
STATIC
)
{
isNeedPack
=
buildPackForCycle
(
transferRule
,
planAst
,
pack
);
}
else
{
isNeedPack
=
buildPackForStatic
(
planBase
,
planAst
,
pack
);
}
if
(
isNeedPack
)
{
return
pack
;
}
return
null
;
}
private
boolean
buildPackForStatic
(
PlanBase
planBase
,
PlanAst
planAst
,
final
Pack
pack
)
{
// 填充计划投资结构
planBase
.
setInvestStructureList
(
planInvestStructureManager
.
selectByPlanNo
(
planBase
.
getPlanNo
()));
// 获取计划投资结构 投入资本金额总额
Money
avalAmt
=
RptBuilderUtil
.
getInvestedAmt
(
planBase
).
subtract
(
planAst
.
getAccGrant
());
if
(
avalAmt
.
isGreaterThanZero
())
{
pack
.
setAvalAmt
(
avalAmt
);
return
true
;
}
else
{
return
false
;
}
}
private
boolean
buildPackForCycle
(
PlanTransferRule
transferRule
,
PlanAst
planAst
,
final
Pack
pack
)
{
// 1. 转让周期判断 数量会越来越大,OOM风险
//List<Pack> packList = packRepository.getByPlanNo(transferRule.getPlanNo());
Date
lastDate
=
null
;
// 当天可以多次转让
//packList = packList.stream().filter(item -> !DateTimeUtil.isSameDay(item.getScenDate(), pack.getScenDate()))
// .collect(Collectors.toList());
//if (CollectionUtils.isNotEmpty(packList)) {
//
// Collections.sort(packList, Comparator.comparing(Pack::getScenDate));
// Pack lastPack = packList.get(packList.size() - 1);
// lastDate = lastPack.getScenDate();
//}
Money
leastValAmt
=
new
Money
(
0
);
if
(!
isNeedTransAccdFreq
(
transferRule
,
leastValAmt
,
pack
.
getScenDate
()))
{
return
false
;
}
// 获取当前实际可用余额
Money
ableCash
=
planAst
.
containClearAbleBal
();
Money
avalAmt
=
ableCash
.
subtract
(
transferRule
.
getResAmt
());
if
(
avalAmt
.
isGreaterThanZero
()
&&
avalAmt
.
greaterThan
(
leastValAmt
))
{
pack
.
setAvalAmt
(
avalAmt
);
Date
minEndDate
=
null
;
Date
maxEndDate
=
null
;
for
(
AstScreenRule
astScreenRule
:
transferRule
.
getAstScreenRuleList
())
{
if
(
astScreenRule
.
getEarliestEndDate
()
!=
null
)
{
if
(
null
==
minEndDate
||
DateTimeUtil
.
calcDayDiff
(
minEndDate
,
astScreenRule
.
getEarliestEndDate
())
>
0
)
{
minEndDate
=
astScreenRule
.
getEarliestEndDate
();
}
}
if
(
astScreenRule
.
getLatestEndDate
()
!=
null
)
{
if
(
null
==
maxEndDate
||
DateTimeUtil
.
calcDayDiff
(
astScreenRule
.
getLatestEndDate
(),
maxEndDate
)
>
0
)
{
maxEndDate
=
astScreenRule
.
getLatestEndDate
();
}
}
}
pack
.
setMinEndDate
(
minEndDate
);
// 默认不能出头,填入值为计划到期日
if
(
null
!=
maxEndDate
)
{
pack
.
setMaxEndDate
(
maxEndDate
);
}
return
true
;
}
else
{
LogUtil
.
info
(
LOGGER
,
"Pack生成忽略PlanNo:{0},avalAmt:{1},leastValAmt:{2}"
,
transferRule
.
getPlanNo
(),
avalAmt
,
leastValAmt
);
return
false
;
}
}
/**
* 目前一天资产同步一次,当资产每天同步多次时需要调整
* @param planTransferRule
* @param leastValAmt
* @param curDate
* @return
*/
private
boolean
isNeedTransAccdFreq
(
PlanTransferRule
planTransferRule
,
Money
leastValAmt
,
Date
curDate
)
{
Pack
lastPack
=
astPackManager
.
getLastDayPackByPlanNo
(
planTransferRule
.
getPlanNo
(),
curDate
);
// 首次转让
if
(
lastPack
==
null
)
{
return
true
;
}
long
dayDiff
=
DateTimeUtil
.
calcDayDiff
(
curDate
,
lastPack
.
getScenDate
());
int
compareDays
=
0
;
switch
(
planTransferRule
.
getTrCycle
())
{
case
D:
compareDays
=
1
;
break
;
case
W:
compareDays
=
7
;
break
;
case
M:
compareDays
=
30
;
break
;
case
Q:
compareDays
=
90
;
break
;
case
Y:
compareDays
=
360
;
break
;
}
if
(
dayDiff
>=
compareDays
)
{
return
true
;
}
return
false
;
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/PlanAstStatTaskHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
com.abssqr.plat.common.facade.enums.OrgAstStatStatusEnum
;
import
com.abssqr.plat.common.facade.enums.SyncTaskTypeEnum
;
import
com.abssqr.plat.common.facade.model.plan.PlanAst
;
import
com.abssqr.plat.common.facade.model.plan.PlanBase
;
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.clearing.PlanClearingLogRepo
;
import
com.abssqr.plat.common.model.repo.plan.PlanAstRepository
;
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.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.SystemDateUtil
;
import
com.general.system.common.util.VarChecker
;
import
com.general.system.tool.util.ToolUtil
;
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.handler: PlanAstStatTaskHandler.java, v 0.1 2019-07-14 16:33 zhenxuan.luo Exp $
*/
@Component
public
class
PlanAstStatTaskHandler
{
protected
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanAstStatTaskHandler
.
class
);
@Autowired
private
PlanAstRepository
planAstRepository
;
@Autowired
private
PlanClearingLogRepo
planClearingLogRepo
;
@Autowired
private
PlanAstStatTaskRepo
planAstStatTaskRepo
;
@Autowired
private
PlanSyncTaskCtrManager
planSyncTaskCtrManager
;
@Autowired
private
PlanManager
planManager
;
/**
* 针对计划生成当日 统计任务
*
* @param planNo
*/
public
void
handle
(
String
planNo
,
Day
trfDate
)
{
// 查询锁水位表
PlanAst
planAst
=
planAstRepository
.
lockByPlanNo
(
planNo
);
VarChecker
.
checkNotNull
(
planAst
,
"计划[{0}]资产水位信息未初始化"
,
planNo
);
// 查询计划下的资产统计任务
PlanAstStatTask
planAstStatTask
=
planAstStatTaskRepo
.
getPlanNo
(
planAst
.
getPlanNo
());
boolean
isNew
=
false
;
// 1. 如果统计任务不存在,则新建
if
(
null
==
planAstStatTask
)
{
// 从未进行统计
planAstStatTask
=
this
.
initplanAstStatTask
(
planAst
);
isNew
=
true
;
}
else
if
(
planAstStatTask
.
getStatus
()
!=
OrgAstStatStatusEnum
.
WAIT
)
{
return
;
}
// 2. 如果统计任务是新建的或者当前日期大于统计任务的会计日期,则重新捞取会计日期
if
(
isNeedResetAccountDate
(
planAstStatTask
.
getAccountDate
(),
planAstStatTask
.
getPlanNo
(),
trfDate
))
{
Date
minAcctDate
=
planClearingLogRepo
.
getMinUnStateAccountDate
(
planAstStatTask
.
getPlanNo
(),
null
);
if
(
null
==
minAcctDate
)
{
// 没有待处理的流水,直接更新
planAstStatTask
.
setAccountDate
(
trfDate
.
getStandardDate
());
planAst
.
setLastUpdateDate
(
planAstStatTask
.
getAccountDate
());
planAstRepository
.
update
(
planAst
);
}
else
{
// 注意:有可能仍然是原来的会计日期,因为有部分流水没处理完
if
(
DateTimeUtil
.
calcDayDiff
(
minAcctDate
,
planAstStatTask
.
getAccountDate
())
<=
0
)
{
LogUtil
.
warn
(
LOGGER
,
"计划统计任务[{0}]初始化,重置日期后,仍然为当日,可能有部分任务阻塞"
,
planAstStatTask
);
}
planAstStatTask
.
setAccountDate
(
minAcctDate
);
}
}
// 重置任务状态为活跃
resetTaskState
(
planAstStatTask
);
// 4. 若任务不存在,则生成任务。若任务存在,则将任务状态修订为执行中,等待dispatcher捞起。(如果已经在执行中则忽略)
if
(
isNew
)
{
planAstStatTaskRepo
.
createTask
(
planAstStatTask
);
}
else
{
planAstStatTaskRepo
.
updateTask
(
planAstStatTask
);
}
}
private
void
resetTaskState
(
PlanAstStatTask
planAstStatTask
)
{
planAstStatTask
.
setStatus
(
OrgAstStatStatusEnum
.
ACTIVE
);
planAstStatTask
.
setLastExecTime
(
planAstStatTask
.
getNextExecTime
());
planAstStatTask
.
setNextExecTime
(
SystemDateUtil
.
getSystemDate
());
planAstStatTask
.
setLastHost
(
null
);
planAstStatTask
.
setExecTimes
(
0L
);
}
private
PlanAstStatTask
initplanAstStatTask
(
PlanAst
planAst
)
{
PlanAstStatTask
planAstStatTask
=
new
PlanAstStatTask
();
planAstStatTask
.
setPlanNo
(
planAst
.
getPlanNo
());
planAstStatTask
.
setAccountDate
(
planAst
.
getLastUpdateDate
());
// 时间戳字段不做消费,只做登记便于排查问题
planAstStatTask
.
setLastExecTms
(
""
);
planAstStatTask
.
setMinId
(
0L
);
planAstStatTask
.
setMaxId
(
0L
);
planAstStatTask
.
setCnt
(
0L
);
return
planAstStatTask
;
}
/**
* 判断是否重置日期
*
* @param taskAccountDate
* @param planNo
* @return
*/
private
boolean
isNeedResetAccountDate
(
Date
taskAccountDate
,
String
planNo
,
Day
trfDate
)
{
Date
standardTaskDate
=
DateTimeUtil
.
getStandardDate
(
taskAccountDate
);
// 当前转让会计日期 小于 任务日 不重置日期
if
(
ToolUtil
.
isNotEmpty
(
standardTaskDate
)
&&
DateTimeUtil
.
calcDayDiff
(
trfDate
.
getStandardDate
(),
standardTaskDate
)
<=
0
)
{
return
false
;
}
// 任务日跨天+10分钟 大于 转让会计日 不重置日期
Date
refDate
=
DateTimeUtil
.
addMinutes
(
DateTimeUtil
.
addDays
(
standardTaskDate
,
1
),
10
);
if
(
refDate
.
compareTo
(
trfDate
.
getDate
())
>
0
)
{
return
false
;
}
// 取转让会计日-1 作为机构会计日判断是否完成模型转换
Date
orgDate
=
trfDate
.
getYesterday
().
getStandardDate
();
PlanBase
planBase
=
planManager
.
getPlanFullByNo
(
planNo
);
return
planSyncTaskCtrManager
.
checkSyncFinishGtIsTrue
(
planBase
,
orgDate
,
SyncTaskTypeEnum
.
AST_MOD
);
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/handler/PlanCashFrozenHandler.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
handler
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.date.DateUtil
;
import
com.abssqr.plat.common.facade.enums.AbssqrNoticeTypeEnum
;
import
com.abssqr.plat.common.facade.enums.PlanAllocStatusEnum
;
import
com.abssqr.plat.common.facade.enums.PlanTypeEnum
;
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.PlanBase
;
import
com.abssqr.plat.common.facade.model.plan.PlanTransferRule
;
import
com.abssqr.plat.common.model.domain.plan.PlanAstLog
;
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.PlanTransferRuleRepo
;
import
com.abssqr.plat.core.service.notice.AbssqrNoticeManager
;
import
com.abssqr.plat.core.service.plan.PlanAllocAmtCalcManager
;
import
com.abssqr.plat.core.service.plan.PlanAstManager
;
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
com.general.system.tool.util.ToolUtil
;
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.Iterator
;
import
java.util.List
;
import
java.util.stream.Collectors
;
/**
* 计算计划每日为分配兑付 预留冻结金额
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.handler: PlanCashFrozenHandler.java, v 0.1 2019-06-13 15:39 zhenxuan.luo Exp $
*/
@Component
public
class
PlanCashFrozenHandler
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanCashFrozenHandler
.
class
);
private
final
static
int
DAY_OFFSET
=
15
;
@Autowired
private
AbssqrNoticeManager
abssqrNoticeManager
;
@Autowired
private
PlanAstManager
planAstManager
;
@Autowired
private
PlanAllocRepo
planAllocRepo
;
@Autowired
private
PlanTransferRuleRepo
planTransferRuleRepo
;
@Autowired
private
PlanAllocAmtCalcManager
planAllocAmtCalcManager
;
@Autowired
private
PlanAcctTitleRepo
planAcctTitleRepo
;
/**
* 资金冻结:需要在外部起事务,保证冻结和任务状态一致,避免重复冻结
* @param planEntity 计划
* @param curDate 转让会计日
*/
public
void
execute
(
PlanBase
planEntity
,
Date
curDate
)
{
LogUtil
.
info
(
LOGGER
,
"执行{0}[{1}]水位冻结任务"
,
planEntity
.
getPlanType
().
getDesc
(),
planEntity
.
getPlanNo
());
// 1. 查找未来最近的分配计划,考虑最近期限(15天)之内多个分配计划日期较近的全部进行判断处理
List
<
PlanAlloc
>
planAllocList
=
planAllocRepo
.
queryUnassigneAllocByPlanNo
(
planEntity
.
getPlanNo
());
if
(
ToolUtil
.
isEmpty
(
planAllocList
))
{
LogUtil
.
warn
(
LOGGER
,
"没有找到{0}[{1}]的最近未来分配计划, 当前时间[{1}]"
,
planEntity
.
getPlanType
().
getDesc
(),
planEntity
.
getPlanNo
(),
curDate
);
return
;
}
// 2. 判断分配当期是否处于循环期,若不属于循环期,不做资金预留
if
(!
this
.
filteNeedFrozenAllocs
(
curDate
,
planAllocList
,
planEntity
))
{
return
;
}
// 3. 计算分配日需要分配的资金 填充需要分配的本金 费用 等金额
List
<
PlanAcctTitle
>
planAcctTitles
=
planAcctTitleRepo
.
getByEntityNo
(
planEntity
.
getPlanNo
());
planAllocAmtCalcManager
.
calcTriAmtByScheduler
(
planEntity
,
planAllocList
,
planAcctTitles
,
true
);
// 计算合计总共需要兑付金额
Money
totalAllocAmt
=
new
Money
();
// 多个分配兑付日
String
clearDates
=
CollectionUtil
.
join
(
planAllocList
.
stream
().
map
(
alloc
->
{
totalAllocAmt
.
addTo
(
alloc
.
calcTotalTrialAmt
());
return
DateUtil
.
formatDate
(
alloc
.
getClearDate
());
}).
collect
(
Collectors
.
toList
()),
","
);
// 计算并执行每日冻结水位资金
PlanAstLog
planAstLog
=
planAstManager
.
calcFrozen
(
curDate
,
planEntity
.
getPlanNo
(),
planAllocList
,
clearDates
);
// 4. 计算近30天的日均还款
Date
startDate
=
DateTimeUtil
.
addDays
(
curDate
,
-
31
);
Date
endDate
=
DateTimeUtil
.
addDays
(
curDate
,
-
1
);
startDate
=
(
startDate
.
compareTo
(
planEntity
.
getEffectDate
())
>
0
)
?
startDate
:
planEntity
.
getEffectDate
();
/**
* 获取每日变更水位的还款金额
* 放款池计算还款包含了承接池的还款-- 因为承接池还会转让将资金转回放款池,所以暂时不计
*/
Money
avgRepoAmt
=
planAstManager
.
getRepayTransAmtStat
(
planEntity
.
getPlanNo
(),
startDate
,
endDate
,
true
);
if
(
planAstLog
.
getFrozenCashAmt
().
greaterThan
(
avgRepoAmt
)
&&
planAstLog
.
getFrozenCash
().
greaterThan
(
planAstLog
.
getCash
()))
{
// 提醒优化,可能计划本来就有很多钱,这个时候还款金额是不是足够其实不重要
String
msg
=
MessageUtil
.
formatMsg
(
"分配计划日期为[{0}],存在兑付风险,待兑付金额{1}元。平均每日还款金额{2}元,今日冻结金额{3}元,计划资金余额{4}元,计划所有已冻结金额{5}元"
,
clearDates
,
totalAllocAmt
,
avgRepoAmt
,
planAstLog
.
getFrozenCashAmt
(),
planAstLog
.
getCash
(),
planAstLog
.
getFrozenCash
());
// 插入一条通知,每日还款金额小于每日冻结金额
abssqrNoticeManager
.
sendBusinessNotice
(
planEntity
,
planEntity
.
getPlanNo
(),
AbssqrNoticeTypeEnum
.
PlanAllocRisk
,
msg
,
null
);
LogUtil
.
warn
(
LOGGER
,
msg
);
}
}
/**
* 判断是否分配计划是否需要冻结资金
* @param curDate
* @param planAllocs
* @param planBase
* @return
*/
private
boolean
filteNeedFrozenAllocs
(
Date
curDate
,
List
<
PlanAlloc
>
planAllocs
,
PlanBase
planBase
)
{
String
planNo
=
planBase
.
getPlanNo
();
Date
stopTrDate
=
null
;
// 承接池进行判断循环结构及期限
if
(
planBase
.
getPlanType
()
==
PlanTypeEnum
.
PLAN
){
// 查询计划转让规则
PlanTransferRule
transferRules
=
planTransferRuleRepo
.
getByPlanNo
(
planNo
);
if
(
null
==
transferRules
)
{
LogUtil
.
warn
(
LOGGER
,
"没有找到计划[{0}]的转让规则"
,
planNo
);
return
false
;
}
// 非循环结构
if
(!
transferRules
.
getCycle
())
{
LogUtil
.
info
(
LOGGER
,
"计划[{0}]不需要冻结预留资金水位,计划非循环结构[{1}]"
,
planNo
,
transferRules
.
getCycle
());
return
false
;
}
// 循环结果,判断循环期
if
(
DateTimeUtil
.
calcDayDiff
(
curDate
,
transferRules
.
getStopTrDate
())
>=
0
)
{
// 当前日期已经停止循环
LogUtil
.
info
(
LOGGER
,
"计划[{0}]不需要冻结预留资金水位,当期日期[{1}]大于等于循环期[{2}]"
,
planNo
,
curDate
,
transferRules
.
getStopTrDate
());
return
false
;
}
// 转让终止日
stopTrDate
=
transferRules
.
getStopTrDate
();
}
Iterator
<
PlanAlloc
>
it
=
planAllocs
.
iterator
();
while
(
it
.
hasNext
())
{
PlanAlloc
planAlloc
=
it
.
next
();
if
(
planAlloc
.
getStatus
()
==
PlanAllocStatusEnum
.
ASSIGNED
)
{
// 剔除已分配
it
.
remove
();
continue
;
}
if
(
DateTimeUtil
.
calcDayDiff
(
planAlloc
.
getClearDate
(),
curDate
)
>
DAY_OFFSET
)
{
// 距离结算日提前15天预留资金
LogUtil
.
info
(
LOGGER
,
"计划[{0}]不需要冻结预留资金水位,当期日期[{1}]距离最近分配计划结算日[{2}]大于[{3}]天"
,
planNo
,
curDate
,
planAlloc
.
getClearDate
(),
DAY_OFFSET
);
//移除该对象
it
.
remove
();
continue
;
}
if
(
stopTrDate
!=
null
&&
DateTimeUtil
.
calcDayDiff
(
stopTrDate
,
planAlloc
.
getClearDate
())
<
0
)
{
// 分配计划结算日在循环期内,需要冻结
LogUtil
.
info
(
LOGGER
,
"计划[{0}]需要冻结预留资金水位,分配计划[{1}]结算日[{2}]小于循环期[{3}]"
,
planNo
,
planAlloc
.
getAllocNo
(),
planAlloc
.
getClearDate
(),
stopTrDate
);
//移除该对象
it
.
remove
();
continue
;
}
}
if
(
ToolUtil
.
isNotEmpty
(
planAllocs
))
{
// 剩余场景:停止循环日期大于当前日期 且 停止循环日期小于分配计划结算日。保险期间,做资金预留
return
true
;
}
else
{
return
false
;
}
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/listener/PlanMonitorRecordEvent.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
listener
;
import
com.abssqr.plat.common.facade.model.CommonPlanEntity
;
import
com.abssqr.plat.common.facade.model.plan.PlanBase
;
import
com.abssqr.plat.common.facade.model.report.PlanReport
;
import
org.springframework.context.ApplicationEvent
;
/**
*
* @author yangcheng
* @version PlanMonitorRecordEvent.java, v0.12019-07-0414:48 yangchengExp$
*/
public
class
PlanMonitorRecordEvent
extends
ApplicationEvent
{
private
PlanReport
planReport
;
private
PlanBase
planEntity
;
public
PlanMonitorRecordEvent
(
Object
source
,
PlanReport
planReport
,
PlanBase
planEntity
)
{
super
(
source
);
this
.
planReport
=
planReport
;
this
.
planEntity
=
planEntity
;
}
public
PlanReport
getPlanReport
()
{
return
planReport
;
}
public
void
setPlanReport
(
PlanReport
planReport
)
{
this
.
planReport
=
planReport
;
}
public
PlanBase
getPlanEntity
()
{
return
planEntity
;
}
public
void
setPlanEntity
(
PlanBase
planEntity
)
{
this
.
planEntity
=
planEntity
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/listener/PlanMonitorRecordListener.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
listener
;
import
com.abssqr.plat.common.facade.enums.PlanIndicatorEnum
;
import
com.abssqr.plat.common.facade.model.plan.PlanBase
;
import
com.abssqr.plat.common.facade.model.plan.PlanMonitor
;
import
com.abssqr.plat.common.facade.model.report.PlanReport
;
import
com.abssqr.plat.common.facade.utils.CalcUtil
;
import
com.abssqr.plat.common.model.repo.plan.impl.PlanMonitorRecordRepoImpl
;
import
com.abssqr.plat.common.model.repo.plan.impl.PlanMonitorRepoImpl
;
import
com.abssqr.plat.core.service.notice.AbssqrNoticeManager
;
import
com.abssqr.plat.core.service.util.RptBuilderUtil
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.MessageUtil
;
import
com.general.system.common.util.VarChecker
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.context.event.EventListener
;
import
org.springframework.stereotype.Component
;
import
org.springframework.transaction.support.TransactionTemplate
;
import
java.math.BigDecimal
;
import
java.util.List
;
/**
* @author yangcheng
* @version PlanMonitorRecordListener.java, v0.12019-07-0414:22 yangchengExp$
*/
@Component
public
class
PlanMonitorRecordListener
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanMonitorRecordListener
.
class
);
@Autowired
private
PlanMonitorRepoImpl
planMonitorRepo
;
@Autowired
private
PlanMonitorRecordRepoImpl
planMonitorRecordRepo
;
@Autowired
private
AbssqrNoticeManager
abssqrNoticeManager
;
@Autowired
private
TransactionTemplate
transactionTemplate
;
/**
* 更新每日监控事件触发情况
*
* @param orderEvent 监听事件
*/
@EventListener
public
void
planMonitorRecordListener
(
PlanMonitorRecordEvent
orderEvent
)
{
PlanReport
planReport
=
orderEvent
.
getPlanReport
();
VarChecker
.
checkNotNull
(
planReport
);
String
planNo
=
planReport
.
getPlanNo
();
List
<
PlanMonitor
>
planMonitorList
=
planMonitorRepo
.
getByPlan
(
planNo
);
if
(
CollectionUtils
.
isNotEmpty
(
planMonitorList
))
{
transactionTemplate
.
execute
(
status
->
{
for
(
PlanMonitor
planMonitor
:
planMonitorList
)
{
//获取文件名,报表信息
String
reportFieldCode
=
planMonitor
.
getIndicator
().
getReportFieldCode
();
BigDecimal
nowVal
=
RptBuilderUtil
.
getReportVal
(
planReport
,
reportFieldCode
);
// nowVal * 100
CalcUtil
.
calcPercRate
(
nowVal
);
LogUtil
.
info
(
LOGGER
,
"该计划{0}监控指标{1}检测"
,
planMonitor
.
getPlanNo
(),
planMonitor
.
getIndicator
().
getDesc
());
if
(
this
.
allowInsert
(
planMonitor
.
getIndicator
(),
planMonitor
.
getValue
(),
nowVal
))
{
LogUtil
.
info
(
LOGGER
,
"该计划{0}监控指标{1}为{2}已违标{3}"
,
planMonitor
.
getPlanNo
(),
planMonitor
.
getIndicator
(),
planMonitor
.
getValue
(),
nowVal
);
//监控信息表新插入
planMonitorRecordRepo
.
insert
(
planMonitor
,
nowVal
);
//消息通知表新插入
this
.
insertMess
(
orderEvent
.
getPlanEntity
()
,
planMonitor
,
nowVal
);
}
}
return
null
;
});
}
}
/**
* 插入消息通知
*
* @param param
*/
private
void
insertMess
(
PlanBase
planBase
,
PlanMonitor
param
,
BigDecimal
nowVal
)
{
//插入消息通知数据
String
bizCode
=
param
.
getPlanNo
();
PlanIndicatorEnum
bizType
=
param
.
getIndicator
();
String
content
=
MessageUtil
.
formatMsg
(
"指标[{1}] 事项名称[{0}] 标准为[{2}]%,当前为[{3}]%,{}"
,
bizType
.
getDesc
(),
param
.
getName
(),
param
.
getValue
(),
nowVal
,
bizType
.
isTopLimit
()
?
"已超标"
:
"已不足"
);
abssqrNoticeManager
.
sendBusinessNotice
(
planBase
,
bizCode
,
bizType
,
content
,
null
);
}
/**
* 上下限统一判断
*
* @param indicator
* @param repoVal
* @param nowVal
* @return
*/
private
boolean
allowInsert
(
PlanIndicatorEnum
indicator
,
BigDecimal
repoVal
,
BigDecimal
nowVal
)
{
return
indicator
.
isTopLimit
()
?
repoVal
.
compareTo
(
nowVal
)
<
1
:
repoVal
.
compareTo
(
nowVal
)
>
-
1
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/PlanAstStatAmtUtil.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
report
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanAstReportStat
;
import
com.general.system.tool.util.ToolUtil
;
import
java.math.BigDecimal
;
/**
* 统计金额字段计算工具
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.report: PlanAstStatAmtUtil.java, v 0.1 2019-06-28 16:22 zhenxuan.luo Exp $
*/
public
class
PlanAstStatAmtUtil
{
/**
* 总发生额 = 本金总额 + 利息总额 + 罚息总额
* @param stat
* @return
*/
public
static
BigDecimal
getAll
(
PlanAstReportStat
stat
)
{
return
getPrin
(
stat
).
add
(
getAllIntrWithPny
(
stat
));
}
/**
* 本金金额
* @param stat
* @return
*/
public
static
BigDecimal
getPrin
(
PlanAstReportStat
stat
)
{
return
stat
.
getPrinAmt
().
add
(
stat
.
getOvdPrinAmt
()).
getAmount
();
}
/**
* 成本发生额
* @param stat
* @return
*/
public
static
BigDecimal
getCost
(
PlanAstReportStat
stat
)
{
return
ToolUtil
.
isEmpty
(
stat
.
getCost
())
?
BigDecimal
.
ZERO
:
stat
.
getCost
().
getAmount
();
}
/**
* 金融服务费发生额
* @param stat
* @return
*/
public
static
BigDecimal
getOrgDistPftAmt
(
PlanAstReportStat
stat
)
{
return
ToolUtil
.
isEmpty
(
stat
.
getOrgDistpftAmt
())
?
BigDecimal
.
ZERO
:
stat
.
getOrgDistpftAmt
().
getAmount
();
}
/**
* 金融服务费发生额
* @param stat
* @return
*/
public
static
BigDecimal
getOtherFeeAmt
(
PlanAstReportStat
stat
)
{
return
ToolUtil
.
isEmpty
(
stat
.
getOtherFeeAmt
())
?
BigDecimal
.
ZERO
:
stat
.
getOtherFeeAmt
().
getAmount
();
}
/**
* 本罚+息罚+费罚
* @param stat
* @return
*/
public
static
BigDecimal
getAllPny
(
PlanAstReportStat
stat
)
{
return
stat
.
getPrinPenalAmt
().
add
(
stat
.
getIntrPenalAmt
()).
add
(
stat
.
getFeePenalAmt
()).
getAmount
();
}
/**
* 利息发生额+费用发生额
* @param stat
* @return
*/
public
static
BigDecimal
getAllIntr
(
PlanAstReportStat
stat
)
{
// 正常利息 + 逾期利息 + 费用
return
stat
.
getIntrAmt
().
add
(
stat
.
getOvdIntrAmt
()).
add
(
stat
.
getFeeAmt
()).
getAmount
();
}
/**
* 利息总额 + 罚息总额
* @param stat
* @return
*/
public
static
BigDecimal
getAllIntrWithPny
(
PlanAstReportStat
stat
)
{
return
getAllIntr
(
stat
).
add
(
getAllPny
(
stat
));
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/ReportItemFilter.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
report
;
import
cn.hutool.core.util.NumberUtil
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanAstReportStat
;
import
com.abssqr.plat.common.facade.enums.EventCodeEnum
;
import
com.abssqr.plat.common.facade.enums.ReportAstStatTypeEnum
;
import
com.abssqr.plat.common.facade.model.report.ReportKey
;
import
com.abssqr.plat.common.model.convertor.ReportItemStatConvert
;
import
org.springframework.stereotype.Component
;
/**
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.report: ReportItemFIlter.java, v 0.1 2019-06-28 02:27 zhenxuan.luo Exp $
*/
@Component
public
class
ReportItemFilter
{
/**
* 合并统计项
* @param vals
* @return
*/
public
PlanAstReportStat
combine
(
PlanAstReportStat
...
vals
)
{
return
ReportItemStatConvert
.
combine
(
vals
);
}
/**
* 统计累计项
* @param reportStatMap
* @param eventCode
* @param type
* @param vals
* @return
*/
public
PlanAstReportStat
filter
(
ReportStatMap
reportStatMap
,
EventCodeEnum
eventCode
,
ReportAstStatTypeEnum
type
,
String
...
vals
)
{
PlanAstReportStat
res
=
ReportItemStatConvert
.
createReportStat
(
type
,
eventCode
,
""
);
for
(
String
val
:
vals
)
{
PlanAstReportStat
reportStat
=
filteForVal
(
reportStatMap
,
type
,
eventCode
,
val
);
res
.
setAstChg
(
NumberUtil
.
add
(
res
.
getAstChg
()
,
reportStat
.
getAstChg
()).
longValue
());
res
.
setPrinAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getPrinAmt
(),
reportStat
.
getPrinAmt
()));
res
.
setOvdPrinAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getOvdPrinAmt
(),
reportStat
.
getOvdPrinAmt
()));
res
.
setIntrAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getIntrAmt
(),
reportStat
.
getIntrAmt
()));
res
.
setOvdIntrAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getOvdIntrAmt
(),
reportStat
.
getOvdIntrAmt
()));
res
.
setFeeAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getFeeAmt
(),
reportStat
.
getFeeAmt
()));
res
.
setOvdFeeAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getOvdFeeAmt
(),
reportStat
.
getOvdFeeAmt
()));
res
.
setPrinPenalAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getPrinPenalAmt
(),
reportStat
.
getPrinPenalAmt
()));
res
.
setIntrPenalAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getIntrPenalAmt
(),
reportStat
.
getIntrPenalAmt
()));
res
.
setFeePenalAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getFeePenalAmt
(),
reportStat
.
getFeePenalAmt
()));
// 费用
res
.
setOtherFeeAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getOtherFeeAmt
(),
reportStat
.
getOtherFeeAmt
()));
res
.
setOtherFeePenalAmt
(
ReportItemStatConvert
.
addWithNull
(
res
.
getOtherFeePenalAmt
(),
reportStat
.
getOtherFeePenalAmt
()));
res
.
setCost
(
ReportItemStatConvert
.
addWithNull
(
res
.
getCost
(),
reportStat
.
getCost
()));
}
return
res
;
}
private
PlanAstReportStat
filteForVal
(
ReportStatMap
reportStatMap
,
ReportAstStatTypeEnum
type
,
EventCodeEnum
eventCode
,
String
val
)
{
ReportKey
reportKey
=
new
ReportKey
(
type
.
getCode
(),
val
,
eventCode
);
PlanAstReportStat
res
=
reportStatMap
.
get
(
reportKey
);
if
(
res
==
null
)
{
res
=
ReportItemStatConvert
.
createReportStat
(
type
,
eventCode
,
val
);
}
else
{
if
(
res
.
getAstChg
()
==
null
)
{
res
.
setAstChg
(
0L
);
}
}
return
res
;
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/ReportStatMap.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
report
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.PlanAstReportStat
;
import
com.abssqr.plat.common.facade.model.report.ReportKey
;
import
java.util.HashMap
;
import
java.util.List
;
/**
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.report: ReportStatMap.java, v 0.1 2019-06-28 02:54 zhenxuan.luo Exp $
*/
public
class
ReportStatMap
extends
HashMap
<
ReportKey
,
PlanAstReportStat
>
{
private
static
final
long
serialVersionUID
=
-
2765549625728233654L
;
public
static
ReportStatMap
buildReportMap
(
List
<
PlanAstReportStat
>
planAstReportStatList
)
{
ReportStatMap
reportStatMap
=
new
ReportStatMap
();
for
(
PlanAstReportStat
planAstReportStat
:
planAstReportStatList
)
{
ReportKey
key
=
new
ReportKey
(
planAstReportStat
.
getStatType
(),
planAstReportStat
.
getStatVal
(),
planAstReportStat
.
getEventCode
());
reportStatMap
.
put
(
key
,
planAstReportStat
);
}
return
reportStatMap
;
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/wk/WkAstReportBuilder.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
report
.
wk
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.util.NumberUtil
;
import
com.abssqr.plat.biz.shared.report.PlanAstStatAmtUtil
;
import
com.abssqr.plat.biz.shared.report.ReportItemFilter
;
import
com.abssqr.plat.biz.shared.report.ReportStatMap
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.LoanBakDAO
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.LoanAstProfitStat
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.LoanBakFormationItem
;
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.AstFlowTypeEnum
;
import
com.abssqr.plat.common.facade.enums.AstRiskClassEnum
;
import
com.abssqr.plat.common.facade.enums.CommonErrorCodeEnum
;
import
com.abssqr.plat.common.facade.enums.EventCodeEnum
;
import
com.abssqr.plat.common.facade.enums.LoanStatusEnum
;
import
com.abssqr.plat.common.facade.enums.PlanTypeEnum
;
import
com.abssqr.plat.common.facade.enums.ReportAstStatTypeEnum
;
import
com.abssqr.plat.common.facade.enums.ReportDimTypeEnum
;
import
com.abssqr.plat.common.facade.enums.ReportTitleGroupEnum
;
import
com.abssqr.plat.common.facade.enums.ReportTypeEnum
;
import
com.abssqr.plat.common.facade.enums.StageChangeTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TransCodeEnum
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
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.model.report.PlanReportItem
;
import
com.abssqr.plat.common.facade.model.report.ReportField
;
import
com.abssqr.plat.common.facade.model.report.ReporterItemCodeKey
;
import
com.abssqr.plat.common.facade.model.report.Statistics
;
import
com.abssqr.plat.common.facade.model.report.wk.WkAstReportFields
;
import
com.abssqr.plat.common.facade.utils.CalcUtil
;
import
com.abssqr.plat.common.model.domain.plan.PlanAcctTitleLog
;
import
com.abssqr.plat.common.model.enums.OvdDaysTypeEnum
;
import
com.abssqr.plat.common.model.enums.TraderTypeEnum
;
import
com.abssqr.plat.common.model.exception.AbssqrBizException
;
import
com.abssqr.plat.common.model.repo.loanTrans.LoanAstProfitLogRepo
;
import
com.abssqr.plat.common.model.repo.report.PlanReportRepo
;
import
com.abssqr.plat.core.service.report.ReportItemHolder
;
import
com.abssqr.plat.core.service.report.calc.impl.CommonItemCalc
;
import
com.abssqr.plat.core.service.util.RptBuilderUtil
;
import
com.general.system.common.model.Money
;
import
com.general.system.common.util.MessageUtil
;
import
com.general.system.common.util.VarChecker
;
import
com.general.system.tool.util.ToolUtil
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.math.BigDecimal
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
/**
* 日报表统计项生成
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.report: WkReportBuilder.java, v 0.1 2019-06-28 02:19 zhenxuan.luo Exp $
*/
@Component
public
class
WkAstReportBuilder
{
@Autowired
private
ReportItemFilter
reportItemFilter
;
@Autowired
private
PlanReportRepo
planReportRepo
;
@Autowired
private
LoanBakDAO
loanBakDAO
;
@Autowired
private
LoanAstProfitLogRepo
loanAstProfitLogRepo
;
/**
* 资产日报
*
* @param planBase
* @param lastReport
* @param reportField
* @param statLoanBakBal
* @param statAmt
* @param planStatItems
* @param acctTitleLogMap
* @param spvDPlanNos spv计划对应的受让计划编号
* @return
*/
public
List
<
PlanReportItem
>
buildReport
(
PlanBase
planBase
,
PlanReport
lastReport
,
DailyReportDateField
reportField
,
List
<
PlanAstReportStat
>
statLoanBakBal
,
List
<
PlanAstReportStat
>
statAmt
,
List
<
PlanAstReportStat
>
statAccrued
,
List
<
PlanStatItem
>
planStatItems
,
Map
<
ReportTitleGroupEnum
,
List
<
PlanAcctTitleLog
>>
acctTitleLogMap
,
List
<
String
>
spvDPlanNos
)
{
// 统计会计日
Date
accountDate
=
reportField
.
getAccountDate
();
// 余额
ReportStatMap
statLoanBakBalMap
=
ReportStatMap
.
buildReportMap
(
statLoanBakBal
);
// 发生额
ReportStatMap
statAmtMap
=
ReportStatMap
.
buildReportMap
(
statAmt
);
// 每日结息项统计
ReportStatMap
statAccruedMap
=
ReportStatMap
.
buildReportMap
(
statAccrued
);
// 清空初始化
ReportItemHolder
.
clearHolder
();
//受让池报表放款池报表,不同区分开方便以后分开维护,目前能复用考虑的暂时考虑复用
if
(
planBase
.
getPlanType
()
==
PlanTypeEnum
.
PLAN
)
{
//资金分析
ReportItemHolder
.
add
(
this
.
buildPlanCapitalReport
(
planBase
,
accountDate
,
planStatItems
,
lastReport
));
//交易贷款分析
ReportItemHolder
.
add
(
this
.
buildTfrPlanReport
(
planBase
.
getPlanNo
(),
accountDate
,
lastReport
,
statAmtMap
));
}
else
if
(
planBase
.
getPlanType
()
==
PlanTypeEnum
.
SPV
)
{
//查询受让计划报表
Map
<
ReporterItemCodeKey
,
Statistics
>
reportEntityMap
=
Maps
.
newHashMap
();
if
(
CollectionUtils
.
isNotEmpty
(
spvDPlanNos
))
{
spvDPlanNos
.
forEach
(
planNo
->
{
PlanReport
report
=
planReportRepo
.
getReport
(
planNo
,
ReportTypeEnum
.
RPT001
,
reportField
.
desc
());
VarChecker
.
checkNotNull
(
report
,
"[{0}]SPV日报生成失败,找不到对应受让计划[{1}].[{2}]日报"
,
planBase
.
getPlanNo
(),
planNo
,
reportField
.
desc
());
RptBuilderUtil
.
recordedData
(
report
.
getReportItems
(),
reportEntityMap
);
});
}
//资金分析
ReportItemHolder
.
add
(
this
.
buildSpvCapitalReport
(
planBase
,
accountDate
,
planStatItems
,
lastReport
,
statAmtMap
,
reportEntityMap
,
spvDPlanNos
));
//交易贷款分析
ReportItemHolder
.
add
(
this
.
buildTfrSpvReport
(
planBase
.
getPlanNo
(),
accountDate
,
lastReport
,
statAmtMap
,
reportEntityMap
,
spvDPlanNos
));
}
// 资产分析 +核销分析 +逾期分析
ReportItemHolder
.
add
(
this
.
buildAstReport
(
planBase
.
getPlanNo
(),
accountDate
,
lastReport
,
statLoanBakBalMap
));
// 费用及兑付分析
ReportItemHolder
.
add
(
this
.
buildFeeReport
(
planBase
.
getPlanNo
(),
accountDate
,
lastReport
,
acctTitleLogMap
));
// 还款分析
ReportItemHolder
.
add
(
this
.
buildRepoReport
(
planBase
.
getPlanNo
(),
accountDate
,
lastReport
,
statAmtMap
,
statAccruedMap
));
// 五级分类余额统计
ReportItemHolder
.
add
(
this
.
buildAstClzReport
(
planBase
.
getPlanNo
(),
accountDate
,
statLoanBakBalMap
));
// 其余统计项计算
ReportItemHolder
.
add
(
this
.
buildRestItemReport
(
planBase
,
accountDate
,
lastReport
,
acctTitleLogMap
));
// 资产结构统计
ReportItemHolder
.
add
(
this
.
buildAstFormationReport
(
planBase
,
accountDate
));
return
ReportItemHolder
.
getHolder
();
}
/**
* 受让池资金分析
*
* @param planEntity
* @param accountDate
* @param planStatItems
* @param lastReport
* @return
*/
private
List
<
PlanReportItem
>
buildPlanCapitalReport
(
PlanBase
planEntity
,
Date
accountDate
,
List
<
PlanStatItem
>
planStatItems
,
PlanReport
lastReport
)
{
// 当日交易贷款资金发生额
BigDecimal
WK003Amt
=
BigDecimal
.
ZERO
;
// 当日还款资金发生额
BigDecimal
WK004Amt
=
BigDecimal
.
ZERO
;
// 兑付流出资金发生额
BigDecimal
WK005Amt
=
BigDecimal
.
ZERO
;
// 其他流出资金发生额
BigDecimal
WK006Amt
=
BigDecimal
.
ZERO
;
// 其他流入资金发生额
BigDecimal
WK007Amt
=
BigDecimal
.
ZERO
;
// 总流出资金发生额
BigDecimal
WK008Amt
=
BigDecimal
.
ZERO
;
// 总流入资金发生额
BigDecimal
WK009Amt
=
BigDecimal
.
ZERO
;
// 支付应付利息
BigDecimal
WK100Amt
=
BigDecimal
.
ZERO
;
// 放款冲正
BigDecimal
WK101Amt
=
BigDecimal
.
ZERO
;
// 冻结资金
BigDecimal
WK000Amt
=
BigDecimal
.
ZERO
;
// 资金流水上的回购资金流出
BigDecimal
WK146Amt
=
BigDecimal
.
ZERO
;
// 资金流水上的回购资金流入
BigDecimal
WK147Amt
=
BigDecimal
.
ZERO
;
// review一下金额计算逻辑 -- 应该是没影响,
for
(
PlanStatItem
planStatItem
:
planStatItems
)
{
if
(
planStatItem
.
getPlanNo
()
==
null
)
{
continue
;
}
TransCodeEnum
transCode
=
TransCodeEnum
.
getByCode
(
planStatItem
.
getTransCode
());
BigDecimal
frozenCashAmt
=
planStatItem
.
getFrozenCashAmt
().
getAmount
();
//累计冻结发生额
WK000Amt
=
WK000Amt
.
add
(
frozenCashAmt
);
// 获取变更水位完成交易的实际发生额,在途的交易金额 发生额都为0
BigDecimal
amt
=
planStatItem
.
getCashAmt
().
getAmount
();
if
(
BigDecimal
.
ZERO
.
compareTo
(
amt
)
==
0
)
{
continue
;
}
if
(
transCode
.
getFundFlow
()
==
AstFlowTypeEnum
.
FLOW_OUT
)
{
WK008Amt
=
WK008Amt
.
add
(
amt
);
switch
(
transCode
)
{
case
BUY_AST:
WK003Amt
=
WK003Amt
.
add
(
amt
);
break
;
case
ALLOC:
WK005Amt
=
WK005Amt
.
add
(
amt
);
break
;
case
PAY_HANG_INTR:
WK100Amt
=
WK100Amt
.
add
(
amt
);
break
;
case
CAP_ADJ_SUB:
WK006Amt
=
WK006Amt
.
add
(
amt
);
break
;
case
BUY_BACK_IN:
// 回购资产流入,资金流出
WK146Amt
=
WK146Amt
.
add
(
amt
);
break
;
default
:
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"无法识别的计划[{0}]资金处理交易[{1}]"
,
planEntity
.
getPlanNo
(),
transCode
),
CommonErrorCodeEnum
.
INVALID_INTERNAL_MODEL
);
}
}
else
if
(
transCode
.
getFundFlow
()
==
AstFlowTypeEnum
.
FLOW_IN
)
{
WK009Amt
=
WK009Amt
.
add
(
amt
);
switch
(
transCode
)
{
case
REPO:
WK004Amt
=
WK004Amt
.
add
(
amt
);
break
;
case
GRANT_REVERSE:
WK101Amt
=
WK101Amt
.
add
(
amt
);
break
;
case
SELL_AST:
break
;
case
CAP_ADJ_ADD:
case
CAP_INVEST:
WK007Amt
=
WK007Amt
.
add
(
amt
);
break
;
case
BUY_BACK_OUT:
// 回购资产流出,资金流入
WK147Amt
=
WK147Amt
.
add
(
amt
);
break
;
default
:
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"无法识别的计划[{0}]资金处理交易[{1}]"
,
planEntity
.
getPlanNo
(),
transCode
),
CommonErrorCodeEnum
.
INVALID_INTERNAL_MODEL
);
}
}
}
// 上日闲置资金余额
BigDecimal
lastWK001Amt
=
RptBuilderUtil
.
getReportVal
(
lastReport
,
WkAstReportFields
.
WK001
.
getCode
());
// 闲置资金余额 = 上日闲置资金余额 + 总流入 - 总流出
BigDecimal
WK001Amt
=
lastWK001Amt
.
add
(
WK009Amt
).
subtract
(
WK008Amt
);
// 冻结金额 - 兑付流出资金发生额 = 冻结金额余额
WK000Amt
=
WK000Amt
.
subtract
(
WK005Amt
);
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK000
,
0L
,
WK000Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK001
,
0L
,
WK001Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK003
,
0L
,
WK003Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK004
,
0L
,
WK004Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK005
,
0L
,
WK005Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK006
,
0L
,
WK006Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK007
,
0L
,
WK007Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK008
,
0L
,
WK008Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK009
,
0L
,
WK009Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK100
,
0L
,
WK100Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK101
,
0L
,
WK101Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK135
,
0L
,
WK005Amt
,
lastReport
));
// 弃用: 转让当日应计挂帐利息
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK132
,
0L
,
BigDecimal
.
ZERO
));
// 回购金额的流出
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK146
,
0L
,
WK146Amt
));
// 回购金额的流入
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK147
,
0L
,
WK147Amt
));
return
ret
;
}
/**
* 放款池资金分析
*
* @param planEntity
* @param accountDate
* @param planStatItems
* @param lastReport
* @return
*/
private
List
<
PlanReportItem
>
buildSpvCapitalReport
(
PlanBase
planEntity
,
Date
accountDate
,
List
<
PlanStatItem
>
planStatItems
,
PlanReport
lastReport
,
ReportStatMap
statAmtMap
,
Map
<
ReporterItemCodeKey
,
Statistics
>
reportEntityMap
,
List
<
String
>
planNos
)
{
// 冻结资金
BigDecimal
WK000Amt
=
BigDecimal
.
ZERO
;
//贷款还款资金发生额
BigDecimal
WK004Amt
=
BigDecimal
.
ZERO
;
//兑付流出资金发生额
BigDecimal
WK005Amt
=
BigDecimal
.
ZERO
;
//其他流出资金发生额
BigDecimal
WK006Amt
=
BigDecimal
.
ZERO
;
//其他流入资金发生额
BigDecimal
WK007Amt
=
BigDecimal
.
ZERO
;
// 支付应付利息
BigDecimal
WK100Amt
=
BigDecimal
.
ZERO
;
// 放款冲正
BigDecimal
WK101Amt
=
BigDecimal
.
ZERO
;
//转让贷款资金发生额
BigDecimal
WK112Amt
=
BigDecimal
.
ZERO
;
//新增资产发生额
BigDecimal
WK111Amt
=
BigDecimal
.
ZERO
;
// 回购资金发生额
BigDecimal
WK146Amt
=
BigDecimal
.
ZERO
;
for
(
PlanStatItem
planStatItem
:
planStatItems
)
{
if
(
ToolUtil
.
isOneEmpty
(
planStatItem
,
planStatItem
.
getPlanNo
()))
{
continue
;
}
StageChangeTypeEnum
changeType
=
StageChangeTypeEnum
.
getByCode
(
planStatItem
.
getChangeType
());
TraderTypeEnum
traderType
=
TraderTypeEnum
.
getByCode
(
planStatItem
.
getTraderType
());
TransCodeEnum
transCode
=
TransCodeEnum
.
getByCode
(
planStatItem
.
getTransCode
());
//累计冻结发生额
WK000Amt
=
WK000Amt
.
add
(
planStatItem
.
getFrozenCashAmt
().
getAmount
());
// 获取变更水位完成交易的实际发生额,在途的交易金额 发生额都为0
BigDecimal
amt
=
planStatItem
.
getCashAmt
().
getAmount
();
if
(
BigDecimal
.
ZERO
.
compareTo
(
amt
)
==
0
)
{
continue
;
}
switch
(
transCode
)
{
case
BUY_AST:
// 放款池 资产交易兑付时只记增加
if
(
changeType
==
StageChangeTypeEnum
.
ADD
)
{
WK112Amt
=
WK112Amt
.
add
(
amt
);
}
break
;
case
ALLOC:
WK005Amt
=
WK005Amt
.
add
(
amt
);
break
;
case
PAY_HANG_INTR:
if
(
changeType
==
StageChangeTypeEnum
.
ADD
)
{
WK100Amt
=
WK100Amt
.
add
(
amt
);
}
break
;
case
CAP_ADJ_SUB:
WK006Amt
=
WK006Amt
.
add
(
amt
);
break
;
case
REPO:
if
(
changeType
==
StageChangeTypeEnum
.
ADD
)
{
// 放款池还款总金额 包含承接池还款金额
WK004Amt
=
WK004Amt
.
add
(
amt
);
}
else
if
(
changeType
==
StageChangeTypeEnum
.
SUB
&&
traderType
==
TraderTypeEnum
.
COUNTERPARTY
)
{
// 还款扣减并且为对手方时,还款兑付给承接池需要进行扣减还款金额
WK004Amt
=
WK004Amt
.
subtract
(
amt
);
}
break
;
//冲正发生额放款池无水位记录
case
GRANT_REVERSE:
break
;
case
SELL_AST:
break
;
case
CAP_ADJ_ADD:
case
CAP_INVEST:
WK007Amt
=
WK007Amt
.
add
(
amt
);
break
;
// case BUY_BACK_IN:
// // 针对放款池 从放款户进行回购资金交易,不产生资金流水,不进行统计处理
// break;
default
:
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"无法识别的计划[{0}]资金处理交易[{1}]"
,
planEntity
.
getPlanNo
(),
transCode
),
CommonErrorCodeEnum
.
INVALID_INTERNAL_MODEL
);
}
}
//放款池新增资产统计
PlanAstReportStat
newStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
SYNC
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 还款补偿
PlanAstReportStat
repoComponsateStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
REPAY_COMPONSATE
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 发放冲正
PlanAstReportStat
grantStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
GRANT_REVERSE
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 放款池回购登记 ReportEntity
PlanAstReportStat
buybackStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
BACK_OUT
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
PlanAstReportStat
allNewStat
=
reportItemFilter
.
combine
(
repoComponsateStat
,
newStat
);
//新增贷款统计
WK111Amt
=
PlanAstStatAmtUtil
.
getPrin
(
allNewStat
);
//放款冲统计
WK101Amt
=
PlanAstStatAmtUtil
.
getPrin
(
grantStat
);
// 回购买入资产资金流出发生额
WK146Amt
=
PlanAstStatAmtUtil
.
getCost
(
buybackStat
);
//计算总流入= 还款资金发生额+转让贷款资金发生额+其他流入资金发生额+放款冲正+应付利息
//计算总流入= 还款资金发生额+转让贷款资金发生额+其他流入资金发生额+放款冲正+转让资产应计应收利息+还款服务费
BigDecimal
WK009Amt
=
WK112Amt
.
add
(
WK100Amt
).
add
(
WK007Amt
).
add
(
WK101Amt
).
add
(
WK004Amt
);
//计算总流出=分配兑付+其他流出+放款 + 回购买入资产发生额
BigDecimal
WK008Amt
=
WK005Amt
.
add
(
WK006Amt
.
add
(
WK111Amt
).
add
(
WK146Amt
));
//冻结金额=上一日冻结金额+冻结发生额-分配兑付金额
WK000Amt
=
RptBuilderUtil
.
getReportVal
(
lastReport
,
WkAstReportFields
.
WK000
.
getCode
()).
add
(
WK000Amt
).
subtract
(
WK005Amt
);
//统计回转服付金额=放款池还款+转让发生额+其他流入+应付利息-预冻结金额
BigDecimal
WK110Amt
=
WK004Amt
.
add
(
WK100Amt
).
add
(
WK112Amt
).
subtract
(
WK000Amt
);
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK000
,
0L
,
WK000Amt
));
//闲置资金余额=上一日闲置余额+总流入-总流出
BigDecimal
lastWK001Amt
=
RptBuilderUtil
.
getReportVal
(
lastReport
,
WkAstReportFields
.
WK001
.
getCode
());
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK001
,
0L
,
lastWK001Amt
.
add
(
WK009Amt
).
subtract
(
WK008Amt
)));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK004
,
0L
,
WK004Amt
));
// 兑付流出资金发生额
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK005
,
0L
,
WK005Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK006
,
0L
,
WK006Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK007
,
0L
,
WK007Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK008
,
0L
,
WK008Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK009
,
0L
,
WK009Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK100
,
0L
,
WK100Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK101
,
0L
,
WK101Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK110
,
0L
,
WK110Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK112
,
0L
,
WK112Amt
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK111
,
0L
,
WK111Amt
));
// 弃用: 转让当日应计未收利息和 = 各承接池转让当日应计未付挂帐利息和
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK132
,
reportEntityMap
,
planNos
));
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK135
,
0L
,
WK005Amt
,
lastReport
));
// 回购买入资产资金流出发生额
ret
.
add
(
buildReportItem
(
planEntity
.
getPlanNo
(),
accountDate
,
WkAstReportFields
.
WK146
,
0L
,
WK146Amt
));
return
ret
;
}
/**
* 资产分析 +核销分析 +逾期分析
*
* @param planNo
* @param accountDate
* @param lastPlanReport
* @param statBalMap 余额
* @return
*/
private
List
<
PlanReportItem
>
buildAstReport
(
String
planNo
,
Date
accountDate
,
PlanReport
lastPlanReport
,
ReportStatMap
statBalMap
)
{
// 正常贷款统计
PlanAstReportStat
statusNorStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
STATUS
,
LoanStatusEnum
.
NORMAL
.
getCode
());
// 逾期贷款统计
PlanAstReportStat
statusOvdStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
STATUS
,
LoanStatusEnum
.
OVERDUE
.
getCode
());
// 核销贷款统计
PlanAstReportStat
statusWrtStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
WTF_STATUS
,
YNEnum
.
Y
.
getCode
());
// 逾期91天以上且核销贷款统计
PlanAstReportStat
ovdWtfStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_WTF_STATUS
,
CommonItemCalc
.
COMMON_VAL
);
// 总贷款
PlanAstReportStat
allStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 1-3 本金
PlanAstReportStat
ovd01Stat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_DAYS
,
OvdDaysTypeEnum
.
OD01
.
getCode
());
// 4-30 本金
PlanAstReportStat
ovd02Stat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_DAYS
,
OvdDaysTypeEnum
.
OD02
.
getCode
());
// 31-60 本金
PlanAstReportStat
ovd03Stat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_DAYS
,
OvdDaysTypeEnum
.
OD03
.
getCode
());
// 逾期61天-90天(含)本金余额
PlanAstReportStat
ovd04Stat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_DAYS
,
OvdDaysTypeEnum
.
OD04
.
getCode
());
// 逾期91天-179天本金余额
PlanAstReportStat
ovd05Stat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_DAYS
,
OvdDaysTypeEnum
.
OD05
.
getCode
());
// 逾期180天及以上本金余额
PlanAstReportStat
ovd06Stat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
OVD_DAYS
,
OvdDaysTypeEnum
.
OD06
.
getCode
());
// 获取当日统计新增放款或转入贷款收益金额 通过loanBak的cost 获取所有资产成本
PlanAstReportStat
profitAmt
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
ALL
,
ReportDimTypeEnum
.
ACCRUED
.
getCode
());
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 正常贷款本金余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK010
,
statusNorStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
statusNorStat
)));
// 正常贷款利息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK011
,
statusNorStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
statusNorStat
)));
// 逾期贷款本金余额
PlanReportItem
ovdPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK012
,
statusOvdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
statusOvdStat
));
ret
.
add
(
ovdPrin
);
// 逾期贷款利息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK013
,
statusOvdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
statusOvdStat
)));
// 逾期贷款罚息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK014
,
statusOvdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
statusOvdStat
)));
// 核销贷款本金余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK015
,
statusWrtStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
statusWrtStat
)));
// 核销贷款利息余额(含罚息)
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK016
,
statusWrtStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
statusWrtStat
)));
// 核销贷款利息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt002
,
statusWrtStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
statusWrtStat
)));
// 核销贷款罚息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt003
,
statusWrtStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
statusWrtStat
)));
// 总贷款本金余额
PlanReportItem
allPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK017
,
allStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allStat
));
ret
.
add
(
allPrin
);
// 总贷款利息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK018
,
allStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allStat
)));
// 总贷款罚息余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK019
,
allStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
allStat
)));
// 累计资产应计年化收益额
PlanReportItem
profitItem
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK128
,
profitAmt
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
profitAmt
));
ret
.
add
(
profitItem
);
// 加权收益率 = WK128 Σ(每笔借据本金*该笔借据年化收益率)/ 对应资产总本金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK129
,
0L
,
CalcUtil
.
divide
(
profitItem
.
getAmt
(),
profitAmt
.
getPrinAmt
().
getAmount
())));
// 逾期1天-3天(含)本金余额
PlanReportItem
ovd01StatPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK021
,
ovd01Stat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
ovd01Stat
));
ret
.
add
(
ovd01StatPrin
);
// 逾期1天-30天(含)本金余额 1-3 加 4- 30
PlanReportItem
ovd02StatPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK022
,
NumberUtil
.
add
(
ovd01Stat
.
getAstChg
(),
ovd02Stat
.
getAstChg
()).
longValue
(),
NumberUtil
.
add
(
PlanAstStatAmtUtil
.
getPrin
(
ovd01Stat
),
PlanAstStatAmtUtil
.
getPrin
(
ovd02Stat
)));
ret
.
add
(
ovd02StatPrin
);
// 逾期31天-60天(含)本金余额
PlanReportItem
ovd03StatPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK023
,
ovd03Stat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
ovd03Stat
));
ret
.
add
(
ovd03StatPrin
);
// 逾期61天-90天(含)本金余额
PlanReportItem
ovd04StatPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK024
,
ovd04Stat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
ovd04Stat
));
ret
.
add
(
ovd04StatPrin
);
// 逾期91天及以上本金余额 91-179 加 180以上
PlanReportItem
ovd05StatPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK025
,
NumberUtil
.
add
(
ovd05Stat
.
getAstChg
(),
ovd06Stat
.
getAstChg
()).
longValue
(),
NumberUtil
.
add
(
PlanAstStatAmtUtil
.
getPrin
(
ovd05Stat
),
PlanAstStatAmtUtil
.
getPrin
(
ovd06Stat
)));
ret
.
add
(
ovd05StatPrin
);
// 逾期180天及以上本金余额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK118
,
ovd06Stat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
ovd06Stat
)));
// 逾期91天及以上非核销本金余额
PlanReportItem
ovdWtfStatPrin
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt001
,
ovdWtfStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
ovdWtfStat
));
ret
.
add
(
ovdWtfStatPrin
);
/*** 计算分级逾期率 ***/
// 整体逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK020
,
ovdPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovdPrin
.
getAmt
(),
allPrin
.
getAmt
())));
// M3+以上逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK026
,
ovd05StatPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovd05StatPrin
.
getAmt
(),
allPrin
.
getAmt
())));
// 整体逾期率(不含宽限期)
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK120
,
ovdPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovdPrin
.
getAmt
().
subtract
(
ovd01StatPrin
.
getAmt
()),
allPrin
.
getAmt
())));
// m0逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK121
,
ovd01StatPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovd01StatPrin
.
getAmt
(),
allPrin
.
getAmt
())));
// m1逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK122
,
ovd02StatPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovd02StatPrin
.
getAmt
(),
allPrin
.
getAmt
())));
// m1+逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK123
,
NumberUtil
.
add
(
ovd03StatPrin
.
getAstCnt
(),
ovd04StatPrin
.
getAstCnt
(),
ovd05StatPrin
.
getAstCnt
()).
longValue
(),
CalcUtil
.
divide
(
NumberUtil
.
add
(
ovd03StatPrin
.
getAmt
(),
ovd04StatPrin
.
getAmt
(),
ovd05StatPrin
.
getAmt
()),
allPrin
.
getAmt
())));
// m2逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK124
,
ovd03StatPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovd03StatPrin
.
getAmt
(),
allPrin
.
getAmt
())));
// m3逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK125
,
ovd04StatPrin
.
getAstCnt
(),
CalcUtil
.
divide
(
ovd04StatPrin
.
getAmt
(),
allPrin
.
getAmt
())));
// M6+逾期率
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK126
,
ovd06Stat
.
getAstChg
(),
CalcUtil
.
divide
(
PlanAstStatAmtUtil
.
getPrin
(
ovd06Stat
),
allPrin
.
getAmt
())));
/**
* 发生额 = 今日余额 - 昨日报表余额
*/
// 当日逾期本金发生额
ret
.
add
(
RptBuilderUtil
.
buildDiffReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK049
,
statusOvdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
statusOvdStat
),
lastPlanReport
));
// 当日逾期利息发生额
ret
.
add
(
RptBuilderUtil
.
buildDiffReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK050
,
statusOvdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
statusOvdStat
),
lastPlanReport
));
// 当日核销本金发生额
ret
.
add
(
RptBuilderUtil
.
buildDiffReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK051
,
statusWrtStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
statusWrtStat
),
lastPlanReport
));
// 当日核销利息发生额(含罚息)
ret
.
add
(
RptBuilderUtil
.
buildDiffReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK052
,
statusWrtStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
statusWrtStat
),
lastPlanReport
));
return
ret
;
}
/**
* 受让池交易贷款分析
*
* @param planNo
* @param accountDate
* @param lastPlanReport
* @param statAmtMap
* @return
*/
private
List
<
PlanReportItem
>
buildTfrPlanReport
(
String
planNo
,
Date
accountDate
,
PlanReport
lastPlanReport
,
ReportStatMap
statAmtMap
)
{
PlanAstReportStat
tfrStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
TRANS_IN
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
/**
* 由于 LoanAstTrManager 中 使用TRANS_OUT 作为转让事件码 所有由原 TRANS_IN 改为 TRANS_OUT
* 兼容 如果 TRANS_OUT 没有时获取TRANS_IN
*/
if
(
BigDecimal
.
ZERO
.
compareTo
(
PlanAstStatAmtUtil
.
getPrin
(
tfrStat
))
==
0
){
tfrStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
TRANS_OUT
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
}
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 累计交易贷款发生
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK027
,
tfrStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getCost
(
tfrStat
),
lastPlanReport
));
// 当日交易贷款发生
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK028
,
tfrStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getCost
(
tfrStat
)));
// 累计交易贷款本金
PlanReportItem
totalTrf
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK102
,
tfrStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
tfrStat
),
lastPlanReport
);
ret
.
add
(
totalTrf
);
// 当日交易贷款本金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK103
,
tfrStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
tfrStat
)));
// 回购卖出资产 对应发生额与本金
PlanAstReportStat
buyBackStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
BACK_OUT
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 累计回购贷款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK144
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getCost
(
buyBackStat
),
lastPlanReport
));
// 当日回购贷款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK145
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getCost
(
buyBackStat
)));
// 累计回购贷款本金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK142
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
buyBackStat
),
lastPlanReport
));
// 当日回购贷款本金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK143
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
buyBackStat
)));
return
ret
;
}
/**
* 放款池交易贷款分析
*
* @param spvNo
* @param accountDate
* @param lastPlanReport
* @param statAmtMap
* @param planNos 对应受让计划编号
* @return
*/
private
List
<
PlanReportItem
>
buildTfrSpvReport
(
String
spvNo
,
Date
accountDate
,
PlanReport
lastPlanReport
,
ReportStatMap
statAmtMap
,
Map
<
ReporterItemCodeKey
,
Statistics
>
reportEntityMap
,
List
<
String
>
planNos
)
{
//增量同步
PlanAstReportStat
grantStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
SYNC
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
//还款补偿,当天放款当天还款数据
PlanAstReportStat
repoComponsateStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
REPAY_COMPONSATE
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
//新增贷款发生额统计 = 增量同步 + 还款补偿
PlanAstReportStat
allPreRepay
=
reportItemFilter
.
combine
(
grantStat
,
repoComponsateStat
);
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 累计交易贷款发生
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK027
,
reportEntityMap
,
planNos
));
// 当日交易贷款发生
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK028
,
reportEntityMap
,
planNos
));
// 累计交易贷款本金
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK102
,
reportEntityMap
,
planNos
));
// 当日交易贷款本金
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK103
,
reportEntityMap
,
planNos
));
// 累计新增贷款
PlanReportItem
totalGrant
=
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK116
,
grantStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allPreRepay
),
lastPlanReport
);
ret
.
add
(
totalGrant
);
// 当日新增资产
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK115
,
grantStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allPreRepay
)));
// 回购买入资产 对应发生额与本金
PlanAstReportStat
buyBackStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
BACK_OUT
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 累计回购贷款发生额
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK144
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getCost
(
buyBackStat
),
lastPlanReport
));
// 当日回购贷款发生额
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK145
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getCost
(
buyBackStat
)));
// 累计回购贷款本金
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK142
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
buyBackStat
),
lastPlanReport
));
// 当日回购贷款本金
ret
.
add
(
buildReportItem
(
spvNo
,
accountDate
,
WkAstReportFields
.
WK143
,
buyBackStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
buyBackStat
)));
return
ret
;
}
/**
* 费用分析
* @param planNo
* @param accountDate
* @param lastReport
* @param acctTitleLogMap
* @return
*/
private
List
<
PlanReportItem
>
buildFeeReport
(
String
planNo
,
Date
accountDate
,
PlanReport
lastReport
,
Map
<
ReportTitleGroupEnum
,
List
<
PlanAcctTitleLog
>>
acctTitleLogMap
)
{
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 获取金融服务费
Money
finFeeAmt
=
RptBuilderUtil
.
getAcctTitleMoney
(
acctTitleLogMap
,
ReportTitleGroupEnum
.
FIN_SER_FEE
);
// 当日金融服务费-->笔数逻辑
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK108
,
finFeeAmt
.
isZero
()
?
0L
:
1L
,
finFeeAmt
.
getAmount
()));
// 累计金融服务费-->如果发生则记一笔,如果没发生则不记一笔
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK109
,
finFeeAmt
.
isZero
()
?
0L
:
1L
,
finFeeAmt
.
getAmount
(),
lastReport
));
// 还款服务费 针对放款池统计时会有 , 承接池没有对应数据
LoanAstProfitStat
repoFee
=
loanAstProfitLogRepo
.
getRepayOrgDistPftAmt
(
accountDate
,
planNo
,
null
);
// 结息还款服务费
Money
repayIntrFeeAmt
=
repoFee
!=
null
?
repoFee
.
getRepayIntrFeeAmt
()
:
new
Money
();
// 实还还款服务费
Money
fundRepayIntrFeeAmt
=
repoFee
!=
null
?
repoFee
.
getFundRepayIntrFeeAmt
()
:
new
Money
();
// 当日结息还款服务费
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK136
,
0L
,
repayIntrFeeAmt
.
getAmount
()));
// 累计结息还款服务费
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK137
,
0L
,
repayIntrFeeAmt
.
getAmount
(),
lastReport
));
// 当日实还还款服务费
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK138
,
0L
,
fundRepayIntrFeeAmt
.
getAmount
()));
// 累计实还还款服务费
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK139
,
0L
,
fundRepayIntrFeeAmt
.
getAmount
(),
lastReport
));
return
ret
;
}
/**
* 还款分析
*
* @param planNo
* @param accountDate
* @param lastPlanReport
* @param statAmtMap
* @return
*/
private
List
<
PlanReportItem
>
buildRepoReport
(
String
planNo
,
Date
accountDate
,
PlanReport
lastPlanReport
,
ReportStatMap
statAmtMap
,
ReportStatMap
statAccrued
)
{
// 到期还款
PlanAstReportStat
allDueRepayStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
DUE_REPAY
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 逾期还款
PlanAstReportStat
allOvdRepayStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
ODUE_REPAY
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 提前还款
PlanAstReportStat
allPreRepayStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
PRE_REPAY
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 还款补偿发生不分类
PlanAstReportStat
allRepayComponsate
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
REPAY_COMPONSATE
,
ReportAstStatTypeEnum
.
ALL
,
CommonItemCalc
.
COMMON_VAL
);
// 到期还款 核销
PlanAstReportStat
wrtDueRepayStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
DUE_REPAY
,
ReportAstStatTypeEnum
.
WTF_STATUS
,
YNEnum
.
N
.
getCode
());
PlanAstReportStat
wrtOvdRepayStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
ODUE_REPAY
,
ReportAstStatTypeEnum
.
WTF_STATUS
,
YNEnum
.
N
.
getCode
());
PlanAstReportStat
wrtPreRepayStat
=
reportItemFilter
.
filter
(
statAmtMap
,
EventCodeEnum
.
PRE_REPAY
,
ReportAstStatTypeEnum
.
WTF_STATUS
,
YNEnum
.
N
.
getCode
());
//到期发生统计--》结息。转让-->增量记结息,存量记结息,同时可能发生转让
PlanAstReportStat
allDueStat
=
reportItemFilter
.
filter
(
statAccrued
,
null
,
ReportAstStatTypeEnum
.
DUE
,
LoanStatusEnum
.
OVERDUE
.
getCode
(),
LoanStatusEnum
.
NORMAL
.
getCode
());
//提前还款--内容组成:还款补偿+提前还款
PlanAstReportStat
allPreRepay
=
reportItemFilter
.
combine
(
allRepayComponsate
,
allPreRepayStat
);
//所有还款记录:到期还款,提前还款,逾期还款
PlanAstReportStat
allRepay
=
reportItemFilter
.
combine
(
allDueRepayStat
,
allOvdRepayStat
,
allPreRepay
);
//核销资产:到期还款,提前还款,逾期还款
PlanAstReportStat
allWrtRepay
=
reportItemFilter
.
combine
(
wrtDueRepayStat
,
wrtOvdRepayStat
,
wrtPreRepayStat
);
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 累计已还本金发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK029
,
allRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allRepay
),
lastPlanReport
));
// 累计已还利息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK030
,
allRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allRepay
),
lastPlanReport
));
// 累计已还罚息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK031
,
allRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
allRepay
),
lastPlanReport
));
// 累计提前还款本金发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK032
,
allPreRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allPreRepay
),
lastPlanReport
));
// 累计提前还款利息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK033
,
allPreRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
allPreRepay
),
lastPlanReport
));
// 累计逾期本金还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK034
,
allOvdRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allOvdRepayStat
),
lastPlanReport
));
// 累计逾期利息还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK035
,
allOvdRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allOvdRepayStat
),
lastPlanReport
));
// 累计逾期罚息还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK036
,
allOvdRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
allOvdRepayStat
),
lastPlanReport
));
// 累计核销本金还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK037
,
allWrtRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allWrtRepay
),
lastPlanReport
));
// 累计核销利息还款发生额(含罚息)
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK038
,
allWrtRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
allWrtRepay
),
lastPlanReport
));
// 当日已还本金发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK039
,
allRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allRepay
)));
// 当日已还利息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK040
,
allRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allRepay
)));
// 当日已还罚息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK041
,
allRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
allRepay
)));
// 当日提前还款本金发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK042
,
allPreRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allPreRepay
)));
// 当日提前还款利息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK043
,
allPreRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
allPreRepay
)));
// 当日逾期本金还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK044
,
allOvdRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allOvdRepayStat
)));
// 当日逾期利息还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK045
,
allOvdRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allOvdRepayStat
)));
// 当日逾期罚息还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK046
,
allOvdRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
allOvdRepayStat
)));
// 当日核销本金还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK047
,
allWrtRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allWrtRepay
)));
// 当日核销利息还款发生额(含罚息)
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK048
,
allWrtRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
allWrtRepay
)));
// 当日计划应还本金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK104
,
allDueStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allDueStat
)));
// 当日计划应还利息
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK105
,
allDueStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allDueStat
)));
// 当日应还已还本金发生额--》应还应该归属到期本金发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK106
,
allDueRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allDueRepayStat
)));
// 当日应还已还利息发生额--》应还应该归属到期利息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK107
,
allDueRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allDueRepayStat
)));
// 当日核销利息还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt006
,
allWrtRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
allWrtRepay
)));
// 当日核销罚息还款发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt007
,
allWrtRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
allWrtRepay
)));
// 当日到期还款本金发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt004
,
allDueRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
allDueRepayStat
)));
// 当日到期还款利息发生额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKExt005
,
allDueRepayStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntrWithPny
(
allDueRepayStat
)));
// 当日提前还款违约金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK140
,
allPreRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getOtherFeeAmt
(
allPreRepay
)));
// 累计提前还款违约金
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK141
,
allPreRepay
.
getAstChg
(),
PlanAstStatAmtUtil
.
getOtherFeeAmt
(
allPreRepay
),
lastPlanReport
));
return
ret
;
}
/**
* 五级分类分析
*
* @param planNo
* @param accountDate
* @param statBalMap
* @return
*/
private
List
<
PlanReportItem
>
buildAstClzReport
(
String
planNo
,
Date
accountDate
,
ReportStatMap
statBalMap
)
{
// 正常贷款统计
PlanAstReportStat
norlStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
AST_CLZ
,
AstRiskClassEnum
.
NORMAL
.
getCode
());
// 关注
PlanAstReportStat
attnStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
AST_CLZ
,
AstRiskClassEnum
.
ATTENTION
.
getCode
());
// 次级
PlanAstReportStat
secdStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
AST_CLZ
,
AstRiskClassEnum
.
SECONDARY
.
getCode
());
// 可疑
PlanAstReportStat
suspStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
AST_CLZ
,
AstRiskClassEnum
.
SUSPICIOUS
.
getCode
());
// 损失
PlanAstReportStat
lossStat
=
reportItemFilter
.
filter
(
statBalMap
,
null
,
ReportAstStatTypeEnum
.
AST_CLZ
,
AstRiskClassEnum
.
LOSS
.
getCode
());
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 正常
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK911
,
norlStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
norlStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK912
,
norlStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
norlStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK913
,
norlStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
norlStat
)));
// 关注
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK921
,
attnStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
attnStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK922
,
attnStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
attnStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK923
,
attnStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
attnStat
)));
// 次级
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK931
,
secdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
secdStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK932
,
secdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
secdStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK933
,
secdStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
secdStat
)));
// 可疑
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK941
,
suspStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
suspStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK942
,
suspStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
suspStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK943
,
suspStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
suspStat
)));
// 损失
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK951
,
lossStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getPrin
(
lossStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK952
,
lossStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllIntr
(
lossStat
)));
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK953
,
lossStat
.
getAstChg
(),
PlanAstStatAmtUtil
.
getAllPny
(
lossStat
)));
return
ret
;
}
/**
* 其余统计项
* 通过线程暂存统计结果进行计算得出
* @param planBase
* @param accountDate
* @param lastPlanReport
* @return
*/
private
List
<
PlanReportItem
>
buildRestItemReport
(
PlanBase
planBase
,
Date
accountDate
,
PlanReport
lastPlanReport
,
Map
<
ReportTitleGroupEnum
,
List
<
PlanAcctTitleLog
>>
acctTitleLogMap
)
{
String
planNo
=
planBase
.
getPlanNo
();
PlanTypeEnum
planType
=
planBase
.
getPlanType
();
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 关于当日投入资本的兑付本金
Money
allocPrin
=
RptBuilderUtil
.
getAcctTitleMoney
(
acctTitleLogMap
,
ReportTitleGroupEnum
.
INVESTED_DAY
);
// 计划当日兑付本金金额
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKPlan001
,
0L
,
allocPrin
.
getAmount
()));
// 计划累计兑付本金金额
PlanReportItem
WKPlan002AmtItem
=
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WKPlan002
,
0L
,
allocPrin
.
getAmount
(),
lastPlanReport
);
ret
.
add
(
WKPlan002AmtItem
);
// 不良率 = WK025逾期91天及以上本金余额 / 承接池:WK102累计交易贷款本金|放款池:WK116累计新增贷款发生额
BigDecimal
denominator
=
ReportItemHolder
.
getPlanReportItemHolder
(
planNo
,
PlanTypeEnum
.
PLAN
==
planType
?
WkAstReportFields
.
WK102
:
WkAstReportFields
.
WK116
);
BigDecimal
ovd05StatPrin
=
ReportItemHolder
.
getPlanReportItemHolder
(
planNo
,
WkAstReportFields
.
WK025
);
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK127
,
0L
,
CalcUtil
.
divide
(
ovd05StatPrin
,
denominator
)));
// // 加权收益率 = WK128 Σ(每笔借据本金*该笔借据年化收益率)/ 承接池:WK102累计交易贷款本金|放款池:WK116累计新增贷款发生额
// BigDecimal profitAmt = ReportItemHolder.getPlanReportItemHolder(planNo, WkAstReportFields.WK128);
// ret.add(buildReportItem(planNo, accountDate, WkAstReportFields.WK129, 0L,
// CalcUtil.divide(profitAmt, denominator)));
// 实际闲置率 = WK001账户余额 /(层级累计规模 - WKPlan002计划累计兑付本金金额)
BigDecimal
WK001ItemAmt
=
ReportItemHolder
.
getPlanReportItemHolder
(
planNo
,
WkAstReportFields
.
WK001
);
Money
investedBal
=
RptBuilderUtil
.
getInvestedBal
(
planBase
,
WKPlan002AmtItem
.
getAmt
());
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK002
,
0L
,
CalcUtil
.
divide
(
WK001ItemAmt
,
investedBal
.
getAmount
())));
// 已实现收益额
Money
WK130Amt
=
PlanTypeEnum
.
PLAN
==
planType
?
RptBuilderUtil
.
getPlanProfitAmt
(
planBase
)
:
RptBuilderUtil
.
getSpvProfitAmt
(
planBase
);
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK130
,
0L
,
WK130Amt
.
getAmount
()));
// 历史本金兑付流水
List
<
PlanAcctTitleLog
>
acctTitleLogs
=
acctTitleLogMap
.
get
(
ReportTitleGroupEnum
.
INVESTED_ALL
);
// 废弃 ((已实现收益额-保证金)*365 + 保证金)/Σ(各信托层级*存续期)
// 已实现收益率 改为 ((已实现收益额)*365)/Σ((各信托层级-保证金)*对应层级存续期)
ret
.
add
(
buildReportItem
(
planNo
,
accountDate
,
WkAstReportFields
.
WK131
,
0L
,
CalcUtil
.
divide
(
WK130Amt
.
multiply
(
planBase
.
getCalcIntrType
().
getAnnualDays
()).
getAmount
(),
RptBuilderUtil
.
getInvestedWeight
(
accountDate
,
planBase
,
acctTitleLogs
,
true
).
getAmount
())));
return
ret
;
}
/**
* 资产结构统计
* @param planBase
* @param accountDate
* @return
*/
private
List
<
PlanReportItem
>
buildAstFormationReport
(
PlanBase
planBase
,
Date
accountDate
){
List
<
PlanReportItem
>
ret
=
Lists
.
newArrayList
();
// 剩余结构
List
<
LoanBakFormationItem
>
astItems
=
loanBakDAO
.
queryAstFormation
(
accountDate
,
planBase
.
getPlanNo
());
CollectionUtil
.
addAll
(
ret
,
RptBuilderUtil
.
convertFormation
(
planBase
.
getPlanNo
(),
accountDate
,
astItems
,
false
));
// 产品结构
List
<
LoanBakFormationItem
>
prodItems
=
loanBakDAO
.
queryProdFormation
(
accountDate
,
planBase
.
getPlanNo
());
CollectionUtil
.
addAll
(
ret
,
RptBuilderUtil
.
convertFormation
(
planBase
.
getPlanNo
(),
accountDate
,
prodItems
,
true
));
return
ret
;
}
/**
* 构建统计项
*
* @param planNo
* @param accountDate
* @param field
* @param cnt
* @param amt
* @return
*/
private
PlanReportItem
buildReportItem
(
String
planNo
,
Date
accountDate
,
ReportField
field
,
Long
cnt
,
BigDecimal
amt
)
{
return
RptBuilderUtil
.
buildReportItem
(
planNo
,
accountDate
,
field
,
cnt
,
amt
);
}
/**
* 构建累计统计项
*
* @param planNo
* @param accountDate
* @param field
* @param cnt
* @param amt
* @param lastPlanReport
* @return
*/
private
PlanReportItem
buildReportItem
(
String
planNo
,
Date
accountDate
,
ReportField
field
,
long
cnt
,
BigDecimal
amt
,
PlanReport
lastPlanReport
)
{
if
(
lastPlanReport
!=
null
)
{
cnt
=
cnt
+
RptBuilderUtil
.
getReportCnt
(
lastPlanReport
,
field
.
getCode
());
amt
=
amt
.
add
(
RptBuilderUtil
.
getReportVal
(
lastPlanReport
,
field
.
getCode
()));
}
return
buildReportItem
(
planNo
,
accountDate
,
field
,
cnt
,
amt
);
}
/**
* 放款池对应承接池 统计项合并计算
* @param spv
* @param accountDate
* @param field
* @param reportEntityMap
* @param plans
* @return
*/
private
PlanReportItem
buildReportItem
(
String
spv
,
Date
accountDate
,
ReportField
field
,
Map
<
ReporterItemCodeKey
,
Statistics
>
reportEntityMap
,
List
<
String
>
plans
)
{
BigDecimal
amt
=
BigDecimal
.
ZERO
;
Long
cnt
=
0L
;
return
buildReportItem
(
spv
,
accountDate
,
field
,
cnt
,
amt
,
reportEntityMap
,
plans
,
null
);
}
/**
* 放款池对应承接池 统计项合并计算并累计
* @param spv
* @param accountDate
* @param field
* @param reportEntityMap
* @param plans
* @return
*/
private
PlanReportItem
buildReportItem
(
String
spv
,
Date
accountDate
,
ReportField
field
,
long
cnt
,
BigDecimal
amt
,
Map
<
ReporterItemCodeKey
,
Statistics
>
reportEntityMap
,
List
<
String
>
plans
,
PlanReport
lastPlanReport
)
{
//1、需要构建key
//2、get values组成amt和cnt
//3、如果有多个受让计划,则需要循环求和
//4、循环结束后进行add,
//5、构建统计项
if
(
CollectionUtils
.
isNotEmpty
(
plans
))
{
for
(
String
plan
:
plans
)
{
ReporterItemCodeKey
reporterKey
=
new
ReporterItemCodeKey
(
plan
,
field
.
getCode
());
Statistics
value
=
reportEntityMap
.
get
(
reporterKey
);
if
(
value
!=
null
)
{
amt
=
amt
.
add
(
value
.
getAmt
());
cnt
=
cnt
+
value
.
getCnt
();
}
}
}
if
(
lastPlanReport
!=
null
){
return
buildReportItem
(
spv
,
accountDate
,
field
,
cnt
,
amt
,
lastPlanReport
);
}
else
{
return
buildReportItem
(
spv
,
accountDate
,
field
,
cnt
,
amt
);
}
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/report/wk/WkManagerReportBuilder.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
report
.
wk
;
import
cn.hutool.core.util.IdcardUtil
;
import
cn.hutool.core.util.NumberUtil
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.LoanBakDAO
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.PropCntStat
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.PropDisbStat
;
import
com.abssqr.plat.common.facade.enums.EventCodeEnum
;
import
com.abssqr.plat.common.facade.enums.IntrTypeEnum
;
import
com.abssqr.plat.common.facade.enums.ReportTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TitleTypeEnum
;
import
com.abssqr.plat.common.facade.model.plan.InvestStructure
;
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.PlanReport
;
import
com.abssqr.plat.common.facade.model.report.PlanReportItem
;
import
com.abssqr.plat.common.facade.model.report.manRpt.AmtPropCnt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.AmtPropCntGroup
;
import
com.abssqr.plat.common.facade.model.report.manRpt.AstRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.CashRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.CommonPropStat
;
import
com.abssqr.plat.common.facade.model.report.manRpt.CommonPropStatGroup
;
import
com.abssqr.plat.common.facade.model.report.manRpt.FeeRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.GrantRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.InvestInfoRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.PlanCommonRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.RepoRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.RiskClzRpt
;
import
com.abssqr.plat.common.facade.model.report.manRpt.TfrRpt
;
import
com.abssqr.plat.common.facade.model.report.wk.WkAstReportFields
;
import
com.abssqr.plat.common.facade.model.report.wk.WkManReportFields
;
import
com.abssqr.plat.common.facade.model.report.wk.WkManagerReport
;
import
com.abssqr.plat.common.facade.utils.CalcUtil
;
import
com.abssqr.plat.common.model.domain.plan.PlanAcctTitleLog
;
import
com.abssqr.plat.common.model.repo.report.PlanReportRepo
;
import
com.abssqr.plat.core.service.util.RptBuilderUtil
;
import
com.alibaba.fastjson.JSON
;
import
com.general.system.common.model.BaseEntity
;
import
com.general.system.common.model.Money
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.VarChecker
;
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.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
java.math.BigDecimal
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
/**
*
* @author zhenxuan.luo
* @version com.abssqr.plat.biz.shared.report.wk: WkManagerReportBuilder.java, v 0.1 2019-07-01 01:39 zhenxuan.luo Exp $
*/
@Component
public
class
WkManagerReportBuilder
{
private
static
List
<
Integer
>
AGE_SPLIT
=
Lists
.
newArrayList
(
22
,
34
,
44
,
55
);
private
static
Integer
LOC_CNT
=
10
;
@Autowired
private
PlanReportRepo
planReportRepo
;
@Autowired
private
LoanBakDAO
loanBakDAO
;
/**
* 供报表下载用,合并跨周期的计划报表
*
* @param planBase
* @param startRptDt
* @param endRptDt
* @return
*/
public
WkManagerReport
getReport
(
PlanBase
planBase
,
String
startRptDt
,
String
endRptDt
)
{
List
<
PlanReport
>
wkManagerReports
=
planReportRepo
.
getPlansByDate
(
planBase
.
getPlanNo
(),
startRptDt
,
endRptDt
,
ReportTypeEnum
.
RPT002
);
if
(
CollectionUtils
.
isEmpty
(
wkManagerReports
))
{
return
null
;
}
WkManagerReport
combinedReport
=
new
WkManagerReport
();
if
(
wkManagerReports
.
size
()
==
1
)
{
combinedReport
=
JSON
.
parseObject
(
wkManagerReports
.
get
(
0
).
getDetail
(),
WkManagerReport
.
class
);
}
else
{
Collections
.
sort
(
wkManagerReports
,
Comparator
.
comparing
(
item
->
item
.
getRptDate
().
desc
()));
combinedReport
.
setPlanNo
(
planBase
.
getPlanNo
());
combinedReport
.
setPlanName
(
planBase
.
getPlanName
());
BigDecimal
avgProfitTotal
=
BigDecimal
.
ZERO
;
BigDecimal
dailyAvgPrinTotal
=
BigDecimal
.
ZERO
;
BigDecimal
dailyAvgPrinExtTotal
=
BigDecimal
.
ZERO
;
for
(
int
i
=
0
;
i
<
wkManagerReports
.
size
();
i
++)
{
WkManagerReport
wkManagerReport
=
JSON
.
parseObject
(
wkManagerReports
.
get
(
i
).
getDetail
(),
WkManagerReport
.
class
);
//日均收益率 日均贷款余额(含核销贷款)日均贷款余额(不含核销贷款)
avgProfitTotal
=
avgProfitTotal
.
add
(
wkManagerReport
.
getCommonRpt
().
getAvgProfit
());
dailyAvgPrinTotal
=
dailyAvgPrinTotal
.
add
(
wkManagerReport
.
getCommonRpt
().
getDailyAvgPrin
());
dailyAvgPrinExtTotal
=
dailyAvgPrinExtTotal
.
add
(
wkManagerReport
.
getCommonRpt
().
getDailyAvgPrinExt
());
//兑付信息
Map
<
String
,
InvestInfoRpt
>
investInfoRptMap
=
wkManagerReport
.
getInvestRpts
().
stream
().
collect
(
Collectors
.
toMap
(
InvestInfoRpt:
:
getInvestNo
,
item
->
item
));
//资金使用情况 总流入 总流出
combinedReport
.
getCashRpt
().
combineAmt
(
wkManagerReport
.
getCashRpt
());
//转让情况 期间转让金额 期间转让笔数
combinedReport
.
getTfrRpt
().
combineAmt
(
wkManagerReport
.
getTfrRpt
());
//放款情况 期间放款金额 期间放款笔数
combinedReport
.
getGrantRpt
().
combineAmt
(
wkManagerReport
.
getGrantRpt
());
//回收情况 到期还款 提前还款 逾期还款 核销还款
combinedReport
.
getRepoRpt
().
combineAmt
(
wkManagerReport
.
getRepoRpt
());
//费用支出 费用名称 费用编号 科目编号 支出时间 费用金额 增值税金额
combinedReport
.
getFeeRpts
().
addAll
(
wkManagerReport
.
getFeeRpts
());
if
(
i
==
0
)
{
//报告开始日期
combinedReport
.
setRptStartDate
(
wkManagerReport
.
getRptStartDate
());
//兑付信息
combinedReport
.
setInvestRpts
(
wkManagerReport
.
getInvestRpts
());
//资金使用情况 期初余额
combinedReport
.
getCashRpt
().
copyPre
(
wkManagerReport
.
getCashRpt
());
//转让情况 期初累计转让金额 期初累计转让笔数
combinedReport
.
getTfrRpt
().
copyPre
(
wkManagerReport
.
getTfrRpt
());
//放款情况 期初累计放款金额 期初累计放款笔数
combinedReport
.
getGrantRpt
().
copyPre
(
wkManagerReport
.
getGrantRpt
());
}
else
if
(
i
==
wkManagerReports
.
size
()
-
1
)
{
//结束时间
combinedReport
.
setRptEndDate
(
wkManagerReport
.
getRptEndDate
());
//计划分析 合同不良率 静态不良率 报备不良率 实际不良率
combinedReport
.
getCommonRpt
().
copyAft
(
wkManagerReport
.
getCommonRpt
());
//兑付信息
for
(
InvestInfoRpt
infoRpt
:
combinedReport
.
getInvestRpts
())
{
InvestInfoRpt
lastInfoRpt
=
investInfoRptMap
.
get
(
infoRpt
.
getInvestNo
());
infoRpt
.
combineAmt
(
lastInfoRpt
);
infoRpt
.
copyAft
(
lastInfoRpt
);
}
//资金使用情况 期末余额
combinedReport
.
getCashRpt
().
copyAft
(
wkManagerReport
.
getCashRpt
());
//转让情况 期末累计转让金额 期末累计转让笔数
combinedReport
.
getTfrRpt
().
copyAft
(
wkManagerReport
.
getTfrRpt
());
//放款情况 期末累计放款金额 期末累计放款笔数
combinedReport
.
getGrantRpt
().
copyAft
(
wkManagerReport
.
getGrantRpt
());
//资产特征 正常 逾期 核销
combinedReport
.
setAstRpt
(
wkManagerReport
.
getAstRpt
());
//五级分类
combinedReport
.
setRiskClzRpt
(
wkManagerReport
.
getRiskClzRpt
());
//统计属性集合
combinedReport
.
setCommonPropStat
(
wkManagerReport
.
getCommonPropStat
());
//计数属性集合
combinedReport
.
setPropCnt
(
wkManagerReport
.
getPropCnt
());
}
else
{
for
(
InvestInfoRpt
infoRpt
:
combinedReport
.
getInvestRpts
())
{
InvestInfoRpt
curInfoRpt
=
investInfoRptMap
.
get
(
infoRpt
.
getInvestNo
());
infoRpt
.
combineAmt
(
curInfoRpt
);
}
}
}
long
days
=
DateTimeUtil
.
calcDayDiff
(
combinedReport
.
getRptEndDate
(),
combinedReport
.
getRptStartDate
());
combinedReport
.
setRptDays
(
days
);
combinedReport
.
getCommonRpt
().
setAvgProfit
(
CalcUtil
.
divide
(
avgProfitTotal
,
new
BigDecimal
(
days
)));
combinedReport
.
getCommonRpt
().
setDailyAvgPrin
(
CalcUtil
.
divide
(
dailyAvgPrinTotal
,
new
BigDecimal
(
days
)));
combinedReport
.
getCommonRpt
()
.
setDailyAvgPrinExt
(
CalcUtil
.
divide
(
dailyAvgPrinExtTotal
,
new
BigDecimal
(
days
)));
}
combinedReport
.
sumInvestRpt
();
return
combinedReport
;
}
/**
* 生成管理报表
* @param plan
* @param startDate
* @param endDate
* @param lastReport
* @param planAcctTitles
* @param titleLogs
* @return
*/
public
WkManagerReport
buildReport
(
PlanBase
plan
,
Date
startDate
,
Date
endDate
,
WkManagerReport
lastReport
,
List
<
PlanAcctTitle
>
planAcctTitles
,
List
<
PlanAcctTitleLog
>
titleLogs
)
{
WkManagerReport
report
=
new
WkManagerReport
();
report
.
setPlanNo
(
plan
.
getPlanNo
());
report
.
setPlanName
(
plan
.
getPlanName
());
report
.
setCalcIntrType
(
plan
.
getCalcIntrType
().
getCode
());
report
.
setRptEndDate
(
endDate
);
report
.
setRptStartDate
(
startDate
);
report
.
setRptDays
(
DateTimeUtil
.
calcDayDiff
(
report
.
getRptEndDate
(),
report
.
getRptStartDate
())
+
1
);
// 科目列表
Map
<
String
,
InvestItem
>
acctTitles
=
buildInvestItem
(
planAcctTitles
);
// 科目流水
Map
<
AcctLogKey
,
AcctAmt
>
titleLogAmtSum
=
buildAcctAmtSum
(
titleLogs
);
// 获取计划日期时间段报表数据
List
<
PlanReportItem
>
dailyReports
=
planReportRepo
.
getItemsByDate
(
plan
.
getPlanNo
(),
report
.
getRptStartDate
(),
report
.
getRptEndDate
());
Map
<
String
,
PlanReportItem
>
sumReportItemMap
=
buildSumReportItem
(
dailyReports
);
Map
<
String
,
PlanReportItem
>
latestReportItemMap
=
buildReportItem
(
dailyReports
,
endDate
);
// 计划分析
buildPlanCommonRpt
(
plan
,
report
,
sumReportItemMap
,
latestReportItemMap
);
// 计划兑付分析
buildInvestRpt
(
plan
,
report
,
titleLogAmtSum
,
acctTitles
,
lastReport
);
// 资金使用情况
buildCashRpt
(
plan
,
report
,
sumReportItemMap
,
lastReport
);
// 转让报表
buildTfrReport
(
report
,
sumReportItemMap
,
lastReport
);
// 资产放款情况
buildGrantReport
(
report
,
sumReportItemMap
,
lastReport
);
// 资产特征
buildAstRpt
(
report
,
latestReportItemMap
);
// 资产回收情况
buildRepoRpt
(
report
,
sumReportItemMap
);
// 五级分类
buildRiskClzRpt
(
report
,
latestReportItemMap
);
// 费用
buildFeeRpt
(
report
,
titleLogs
);
// 资产统计特征
buildCommonStat
(
report
,
endDate
);
// 资产属性统计
buildPropCntStat
(
report
,
endDate
);
return
report
;
}
/**
* 计划分析
*
* @param plan
* @param report
* @param sumReportItemMap
* @param latestReportItemMap
*/
private
void
buildPlanCommonRpt
(
PlanBase
plan
,
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
sumReportItemMap
,
Map
<
String
,
PlanReportItem
>
latestReportItemMap
)
{
BigDecimal
rptDays
=
new
BigDecimal
(
report
.
getRptDays
());
PlanCommonRpt
planCommonRpt
=
new
PlanCommonRpt
();
// 总收益=最新应还利息+最新应还罚息+期间累计已还利息+期间累计已还罚息
BigDecimal
profit
=
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK018
.
getCode
())
.
add
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK019
.
getCode
()))
.
add
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK040
.
getCode
()))
.
add
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK041
.
getCode
()));
BigDecimal
profitRate
=
CalcUtil
.
divide
(
profit
,
RptBuilderUtil
.
getInvestedAmt
(
plan
).
getAmount
());
planCommonRpt
.
setAvgProfit
(
CalcUtil
.
divide
(
profitRate
,
rptDays
));
/**
当前月损失率=(近30天新增逾期90天以上的借据的未还剩余本金)/ 近30天平均剩余资产规模(包含核销);
(1-当前年化损失率) 当前年化损失率=当前月损失率*12
*/
BigDecimal
lossYearRate
=
NumberUtil
.
sub
(
1
,
NumberUtil
.
mul
(
CalcUtil
.
divide
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK025
.
getCode
()),
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK017
.
getCode
())),
12
));
// (1-闲置率)闲置率=从成立到当前,每日闲置率的平均值
BigDecimal
idleRate
=
NumberUtil
.
sub
(
1
,
CalcUtil
.
divide
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK002
.
getCode
()),
rptDays
));
// 资产加权利率 累计维度,取准实时值 取最后一日的资产加权利率
BigDecimal
astRate
=
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK129
.
getCode
());
// (1-招联金融服务费率)招联金融服务费费率:在项目录入时输入
BigDecimal
finSerFeeRate
=
NumberUtil
.
sub
(
1
,
plan
.
getFinSerFeeRate
());
/**
* 信托实际收益率(税前) =(1-闲置率)*(1-当前年化损失率)*资产加权利率*(1-招联金融服务费率)+(1-当前年化损失率)
*/
planCommonRpt
.
setProfitRate
(
NumberUtil
.
mul
(
idleRate
,
lossYearRate
,
astRate
,
finSerFeeRate
).
add
(
lossYearRate
));
// 报告期内,=sum(每日贷款余额(包含核销贷款))/统计天数
BigDecimal
prinSum
=
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK017
.
getCode
());
planCommonRpt
.
setDailyAvgPrin
(
CalcUtil
.
divide
(
prinSum
,
rptDays
));
// 报告期内,=sum(每日贷款余额(不包含核销贷款))/统计天数
BigDecimal
prinExtSum
=
prinSum
.
subtract
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK015
.
getCode
()));
planCommonRpt
.
setDailyAvgPrinExt
(
CalcUtil
.
divide
(
prinExtSum
,
rptDays
));
// 91天以上逾期资产(含“181天以上核销”)
BigDecimal
oduePrin
=
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK025
.
getCode
());
// 91天以上逾期资产(不含“181天以上核销”)
BigDecimal
odueExtPrin
=
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WKExt001
.
getCode
());
// 贷款余额
BigDecimal
totalPrin
=
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK017
.
getCode
());
// 累计放款金额
BigDecimal
totalAcctGrant
=
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK027
.
getCode
());
// 91天以上逾期资产(不含“181天以上核销”)/累计放款金额
planCommonRpt
.
setNplCont
(
CalcUtil
.
divide
(
odueExtPrin
,
totalAcctGrant
));
planCommonRpt
.
setNplStatic
(
CalcUtil
.
divide
(
oduePrin
,
totalAcctGrant
));
planCommonRpt
.
setNplReport
(
CalcUtil
.
divide
(
odueExtPrin
,
totalPrin
));
planCommonRpt
.
setNplReal
(
CalcUtil
.
divide
(
oduePrin
,
totalPrin
));
report
.
setCommonRpt
(
planCommonRpt
);
}
/**
* 投资结构和计划兑付信息
* @param plan
* @param report
* @param titleLogAmtSum
* @param acctTitles
* @param lastReport
*/
private
void
buildInvestRpt
(
PlanBase
plan
,
WkManagerReport
report
,
Map
<
AcctLogKey
,
AcctAmt
>
titleLogAmtSum
,
Map
<
String
,
InvestItem
>
acctTitles
,
WkManagerReport
lastReport
)
{
List
<
InvestInfoRpt
>
infoRpts
=
Lists
.
newArrayList
();
Map
<
String
,
InvestInfoRpt
>
lastInfoRptMap
=
Maps
.
newHashMap
();
if
(
null
!=
lastReport
)
{
lastInfoRptMap
=
lastReport
.
getInvestRpts
().
stream
().
collect
(
Collectors
.
toMap
(
InvestInfoRpt:
:
getInvestNo
,
item
->
item
));
}
// 根据投资结构 计算分配兑付情况
for
(
InvestStructure
investStrut
:
plan
.
getInvestStructureList
())
{
// 上个周期的月报,可能为null,需要判断null处理
InvestInfoRpt
lastInfoRpt
=
lastInfoRptMap
.
get
(
investStrut
.
getLayerNo
());
// 对应该投资结构层级的各个科目,不能为null,为null说明科目未初始化,为系统异常
InvestItem
investItem
=
acctTitles
.
get
(
investStrut
.
getLayerNo
());
VarChecker
.
checkNotNull
(
investItem
,
"投资结构[{0}]的科目为初始化"
,
investStrut
);
InvestInfoRpt
infoRpt
=
new
InvestInfoRpt
();
infoRpt
.
setInvestNo
(
investStrut
.
getLayerNo
());
infoRpt
.
setInvestName
(
investStrut
.
getLayerName
());
infoRpt
.
setInvestCost
(
investStrut
.
getLayerAmt
().
getAmount
());
// 考虑无票面利率的情况
if
(
investStrut
.
getIntrType
()
==
IntrTypeEnum
.
NOTICKET
)
{
infoRpt
.
setRate
(
null
);
}
else
{
infoRpt
.
setRate
(
investStrut
.
getLayerIntr
());
}
// 期初本金:上个报表的期末为这个报表的期初,默认为投入资本
infoRpt
.
setPrePrin
((
null
==
lastInfoRpt
)
?
investStrut
.
getLayerAmt
().
getAmount
()
:
lastInfoRpt
.
getAftPrin
());
// 期初收益:上个报表的期末为这个报表的期初,默认为0
infoRpt
.
setPreProfit
((
null
==
lastInfoRpt
)
?
BigDecimal
.
ZERO
:
lastInfoRpt
.
getAftProfit
());
// 从科目流水中,汇总发生额,汇总结果可能为null(该月未发生相关交易),若为null,则作0处理
AcctAmt
prinAcctAmt
=
titleLogAmtSum
.
get
(
new
AcctLogKey
(
investItem
.
investTitle
,
EventCodeEnum
.
TITLE_ALLOC
));
AcctAmt
intrAllocAcctAmt
=
titleLogAmtSum
.
get
(
new
AcctLogKey
(
investItem
.
intrTitle
,
EventCodeEnum
.
TITLE_ALLOC
));
AcctAmt
intrSettleAcctAmt
=
titleLogAmtSum
.
get
(
new
AcctLogKey
(
investItem
.
intrTitle
,
EventCodeEnum
.
TITLE_SETTLE
));
infoRpt
.
setAllocPrinAmt
((
prinAcctAmt
==
null
)
?
BigDecimal
.
ZERO
:
prinAcctAmt
.
amt
);
infoRpt
.
setAllocProfitAmt
((
intrAllocAcctAmt
==
null
)
?
BigDecimal
.
ZERO
:
intrAllocAcctAmt
.
amt
);
infoRpt
.
setAllocVtaxAmt
((
intrAllocAcctAmt
==
null
)
?
BigDecimal
.
ZERO
:
intrAllocAcctAmt
.
vtaxAmt
);
infoRpt
.
setAddProfitAmt
((
intrSettleAcctAmt
==
null
)
?
BigDecimal
.
ZERO
:
intrSettleAcctAmt
.
amt
);
// 期初 +/- 期间发生额 = 期末,不用考虑为null的情况
infoRpt
.
setAftPrin
(
infoRpt
.
getPrePrin
().
subtract
(
infoRpt
.
getAllocPrinAmt
()));
infoRpt
.
setAftProfit
(
infoRpt
.
getPreProfit
().
add
(
infoRpt
.
getAddProfitAmt
()).
subtract
(
infoRpt
.
getAllocProfitAmt
()));
// 汇总本金,收益的累计分配,若上日报表为null,则直接采用当期发生额,否则累加上日报表的汇总金额
infoRpt
.
setTotAllocPrin
((
lastInfoRpt
==
null
)
?
infoRpt
.
getAllocPrinAmt
()
:
infoRpt
.
getAllocPrinAmt
().
add
(
lastInfoRpt
.
getTotAllocPrin
()));
infoRpt
.
setTotAllocProfit
((
lastInfoRpt
==
null
)
?
infoRpt
.
getAllocProfitAmt
()
:
infoRpt
.
getAllocProfitAmt
().
add
(
lastInfoRpt
.
getTotAllocProfit
()));
infoRpt
.
setTotAllocVtax
((
lastInfoRpt
==
null
)
?
infoRpt
.
getAllocVtaxAmt
()
:
infoRpt
.
getAllocVtaxAmt
().
add
(
lastInfoRpt
.
getTotAllocVtax
()));
infoRpts
.
add
(
infoRpt
);
}
report
.
setInvestRpts
(
infoRpts
);
}
/**
* 资金使用情况
* @param plan
* @param report
* @param sumReportItemMap
* @param lastReport
*/
private
void
buildCashRpt
(
PlanBase
plan
,
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
sumReportItemMap
,
WkManagerReport
lastReport
)
{
CashRpt
cashRpt
=
new
CashRpt
();
cashRpt
.
setPreBal
((
lastReport
==
null
)
?
RptBuilderUtil
.
getInvestedAmt
(
plan
).
getAmount
()
:
lastReport
.
getCashRpt
().
getAftBal
());
cashRpt
.
setInAmt
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK009
.
getCode
()));
cashRpt
.
setOutAmt
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK008
.
getCode
()));
cashRpt
.
setAftBal
(
cashRpt
.
getPreBal
().
add
(
cashRpt
.
getInAmt
()).
subtract
(
cashRpt
.
getOutAmt
()));
report
.
setCashRpt
(
cashRpt
);
}
/**
* 资产转让情况
* @param report
* @param sumReportItemMap
* @param lastReport
*/
private
void
buildTfrReport
(
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
sumReportItemMap
,
WkManagerReport
lastReport
)
{
TfrRpt
tfrRpt
=
new
TfrRpt
();
tfrRpt
.
setPreAccGrant
((
lastReport
==
null
)
?
BigDecimal
.
ZERO
:
lastReport
.
getTfrRpt
().
getAftAccGrant
());
tfrRpt
.
setPreAccGrantCnt
((
lastReport
==
null
)
?
BigDecimal
.
ZERO
:
lastReport
.
getTfrRpt
().
getAftAccGrantCnt
());
tfrRpt
.
setGrantAmt
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK028
.
getCode
()));
tfrRpt
.
setGrantCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
sumReportItemMap
,
WkAstReportFields
.
WK028
.
getCode
())));
tfrRpt
.
setAftAccGrant
(
tfrRpt
.
getPreAccGrant
().
add
(
tfrRpt
.
getGrantAmt
()));
tfrRpt
.
setAftAccGrantCnt
(
tfrRpt
.
getPreAccGrantCnt
().
add
(
tfrRpt
.
getGrantCnt
()));
report
.
setTfrRpt
(
tfrRpt
);
}
/**
* 资产放款情况
* @param report
* @param sumReportItemMap
* @param lastReport
*/
private
void
buildGrantReport
(
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
sumReportItemMap
,
WkManagerReport
lastReport
)
{
GrantRpt
grantRpt
=
new
GrantRpt
();
grantRpt
.
setPreAccGrant
((
lastReport
==
null
)
?
BigDecimal
.
ZERO
:
lastReport
.
getGrantRpt
().
getAftAccGrant
());
grantRpt
.
setPreAccGrantCnt
((
lastReport
==
null
)
?
BigDecimal
.
ZERO
:
lastReport
.
getGrantRpt
().
getAftAccGrantCnt
());
grantRpt
.
setGrantAmt
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK115
.
getCode
()));
grantRpt
.
setGrantCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
sumReportItemMap
,
WkAstReportFields
.
WK115
.
getCode
())));
grantRpt
.
setAftAccGrant
(
grantRpt
.
getPreAccGrant
().
add
(
grantRpt
.
getGrantAmt
()));
grantRpt
.
setAftAccGrantCnt
(
grantRpt
.
getPreAccGrantCnt
().
add
(
grantRpt
.
getGrantCnt
()));
report
.
setGrantRpt
(
grantRpt
);
}
/**
* 资产特征
* @param report
* @param latestReportItemMap
*/
private
void
buildAstRpt
(
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
latestReportItemMap
)
{
AstRpt
astRpt
=
new
AstRpt
();
AmtPropCnt
normal
=
new
AmtPropCnt
();
AmtPropCnt
overdue
=
new
AmtPropCnt
();
AmtPropCnt
writeOff
=
new
AmtPropCnt
();
normal
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK010
.
getCode
())));
normal
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK010
.
getCode
()));
normal
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK011
.
getCode
()));
normal
.
calTotal
();
overdue
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK012
.
getCode
())));
overdue
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK012
.
getCode
()));
overdue
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK013
.
getCode
()));
overdue
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK014
.
getCode
()));
overdue
.
calTotal
();
writeOff
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK015
.
getCode
())));
writeOff
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK015
.
getCode
()));
writeOff
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WKExt002
.
getCode
()));
writeOff
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WKExt003
.
getCode
()));
writeOff
.
calTotal
();
astRpt
.
setNormal
(
normal
);
astRpt
.
setOverdue
(
overdue
);
astRpt
.
setWriteoff
(
writeOff
);
report
.
setAstRpt
(
astRpt
);
}
/**
* 资产回收情况
* @param report
* @param sumReportItemMap
*/
private
void
buildRepoRpt
(
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
sumReportItemMap
)
{
RepoRpt
repoRpt
=
new
RepoRpt
();
AmtPropCnt
dueRepo
=
new
AmtPropCnt
();
AmtPropCnt
preRepo
=
new
AmtPropCnt
();
AmtPropCnt
ovdRepo
=
new
AmtPropCnt
();
AmtPropCnt
wrtRepo
=
new
AmtPropCnt
();
dueRepo
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
sumReportItemMap
,
WkAstReportFields
.
WKExt004
.
getCode
())));
dueRepo
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WKExt004
.
getCode
()));
dueRepo
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WKExt005
.
getCode
()));
dueRepo
.
calTotal
();
preRepo
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
sumReportItemMap
,
WkAstReportFields
.
WK042
.
getCode
())));
preRepo
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK042
.
getCode
()));
preRepo
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK043
.
getCode
()));
preRepo
.
setOtherFee
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK140
.
getCode
()));
preRepo
.
calTotal
();
ovdRepo
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
sumReportItemMap
,
WkAstReportFields
.
WK044
.
getCode
())));
ovdRepo
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK044
.
getCode
()));
ovdRepo
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK045
.
getCode
()));
ovdRepo
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK046
.
getCode
()));
ovdRepo
.
calTotal
();
wrtRepo
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
sumReportItemMap
,
WkAstReportFields
.
WK047
.
getCode
())));
wrtRepo
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WK047
.
getCode
()));
wrtRepo
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WKExt006
.
getCode
()));
wrtRepo
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
sumReportItemMap
,
WkAstReportFields
.
WKExt007
.
getCode
()));
wrtRepo
.
calTotal
();
repoRpt
.
setDueRepo
(
dueRepo
);
repoRpt
.
setPreRepo
(
preRepo
);
repoRpt
.
setOvdRepo
(
ovdRepo
);
repoRpt
.
setWrtRepo
(
wrtRepo
);
report
.
setRepoRpt
(
repoRpt
);
}
/**
* 五级分类统计
*
* @param report
* @param latestReportItemMap
*/
private
void
buildRiskClzRpt
(
WkManagerReport
report
,
Map
<
String
,
PlanReportItem
>
latestReportItemMap
)
{
RiskClzRpt
riskClzRpt
=
new
RiskClzRpt
();
AmtPropCnt
normal
=
new
AmtPropCnt
();
AmtPropCnt
atten
=
new
AmtPropCnt
();
AmtPropCnt
second
=
new
AmtPropCnt
();
AmtPropCnt
suspic
=
new
AmtPropCnt
();
AmtPropCnt
loss
=
new
AmtPropCnt
();
AmtPropCnt
total
=
new
AmtPropCnt
();
normal
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK911
.
getCode
())));
normal
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK911
.
getCode
()));
normal
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK912
.
getCode
()));
second
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK913
.
getCode
()));
normal
.
calTotal
();
atten
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK921
.
getCode
())));
atten
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK921
.
getCode
()));
atten
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK922
.
getCode
()));
second
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK923
.
getCode
()));
atten
.
calTotal
();
second
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK931
.
getCode
())));
second
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK931
.
getCode
()));
second
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK932
.
getCode
()));
second
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK933
.
getCode
()));
second
.
calTotal
();
suspic
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK941
.
getCode
())));
suspic
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK941
.
getCode
()));
suspic
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK942
.
getCode
()));
suspic
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK943
.
getCode
()));
suspic
.
calTotal
();
loss
.
setCnt
(
new
BigDecimal
(
RptBuilderUtil
.
getReportCnt
(
latestReportItemMap
,
WkAstReportFields
.
WK951
.
getCode
())));
loss
.
setPrin
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK951
.
getCode
()));
loss
.
setIntr
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK952
.
getCode
()));
loss
.
setPenl
(
RptBuilderUtil
.
getReportVal
(
latestReportItemMap
,
WkAstReportFields
.
WK953
.
getCode
()));
loss
.
calTotal
();
total
.
addAllAmt
(
normal
).
addAllAmt
(
atten
).
addAllAmt
(
second
).
addAllAmt
(
suspic
).
addAllAmt
(
loss
);
normal
.
calcRatio
(
total
);
atten
.
calcRatio
(
total
);
second
.
calcRatio
(
total
);
suspic
.
calcRatio
(
total
);
loss
.
calcRatio
(
total
);
riskClzRpt
.
setNormal
(
normal
);
riskClzRpt
.
setAtten
(
atten
);
riskClzRpt
.
setSecond
(
second
);
riskClzRpt
.
setSuspic
(
suspic
);
riskClzRpt
.
setLoss
(
loss
);
riskClzRpt
.
setTotal
(
total
);
report
.
setRiskClzRpt
(
riskClzRpt
);
}
/**
* 费用报表
*
* @param report
* @param acctTitleLogs
*/
private
void
buildFeeRpt
(
WkManagerReport
report
,
List
<
PlanAcctTitleLog
>
acctTitleLogs
)
{
List
<
FeeRpt
>
feeRpts
=
Lists
.
newArrayList
();
Collections
.
sort
(
acctTitleLogs
,
Comparator
.
comparing
(
PlanAcctTitleLog:
:
getAccountDate
));
for
(
PlanAcctTitleLog
planAcctTitleLog
:
acctTitleLogs
)
{
if
(
planAcctTitleLog
.
getTitleType
()
!=
TitleTypeEnum
.
FEE
)
{
continue
;
}
if
(
planAcctTitleLog
.
getEventCode
()
!=
EventCodeEnum
.
TITLE_ALLOC
)
{
continue
;
}
FeeRpt
feeRpt
=
new
FeeRpt
();
feeRpt
.
setFeeName
(
planAcctTitleLog
.
getTitleName
());
feeRpt
.
setFeeNo
(
planAcctTitleLog
.
getRefNo
());
feeRpt
.
setTitleNo
(
planAcctTitleLog
.
getTitleNo
());
feeRpt
.
setDt
(
DateTimeUtil
.
formatY_M_D
(
planAcctTitleLog
.
getAccountDate
()));
feeRpt
.
setFeeAmt
(
planAcctTitleLog
.
getAcctAmt
().
getAmount
());
feeRpt
.
setVtaxAmt
(
planAcctTitleLog
.
getvTaxAmt
().
getAmount
());
feeRpt
.
setMemo
(
""
);
feeRpts
.
add
(
feeRpt
);
}
report
.
setFeeRpts
(
feeRpts
);
}
private
Map
<
AcctLogKey
,
AcctAmt
>
buildAcctAmtSum
(
List
<
PlanAcctTitleLog
>
planAcctTitleLogs
)
{
Map
<
AcctLogKey
,
AcctAmt
>
ret
=
Maps
.
newHashMap
();
for
(
PlanAcctTitleLog
planAcctTitleLog
:
planAcctTitleLogs
)
{
AcctLogKey
key
=
new
AcctLogKey
(
planAcctTitleLog
.
getTitleNo
(),
planAcctTitleLog
.
getEventCode
());
AcctAmt
amt
=
ret
.
get
(
key
);
if
(
null
==
amt
)
{
amt
=
new
AcctAmt
();
ret
.
put
(
key
,
amt
);
}
amt
.
amt
=
amt
.
amt
.
add
(
planAcctTitleLog
.
getAcctAmt
().
getAmount
());
amt
.
vtaxAmt
=
amt
.
vtaxAmt
.
add
(
planAcctTitleLog
.
getvTaxAmt
().
getAmount
());
}
return
ret
;
}
private
Map
<
String
,
PlanReportItem
>
buildSumReportItem
(
List
<
PlanReportItem
>
dailyReports
)
{
return
buildReportItem
(
dailyReports
,
null
);
}
private
Map
<
String
,
PlanReportItem
>
buildReportItem
(
List
<
PlanReportItem
>
dailyReports
,
Date
accountDate
)
{
Map
<
String
,
PlanReportItem
>
reportItemMap
=
Maps
.
newHashMap
();
for
(
PlanReportItem
item
:
dailyReports
)
{
if
(
accountDate
!=
null
&&
DateTimeUtil
.
calcDayDiff
(
accountDate
,
item
.
getAccountDate
())
!=
0
)
{
continue
;
}
PlanReportItem
sumItem
=
reportItemMap
.
get
(
item
.
getRptItemCode
());
if
(
null
==
sumItem
)
{
sumItem
=
new
PlanReportItem
();
sumItem
.
setRptItemCode
(
sumItem
.
getRptItemCode
());
sumItem
.
setRptItemName
(
sumItem
.
getRptItemName
());
sumItem
.
setAstCnt
(
item
.
getAstCnt
());
sumItem
.
setAmt
(
item
.
getAmt
());
reportItemMap
.
put
(
item
.
getRptItemCode
(),
sumItem
);
}
else
{
sumItem
.
setAstCnt
(
sumItem
.
getAstCnt
()
+
item
.
getAstCnt
());
sumItem
.
setAmt
(
sumItem
.
getAmt
().
add
(
item
.
getAmt
()));
}
}
return
reportItemMap
;
}
private
Map
<
String
,
InvestItem
>
buildInvestItem
(
List
<
PlanAcctTitle
>
planAcctTitles
)
{
Map
<
String
,
InvestItem
>
ret
=
Maps
.
newHashMap
();
for
(
PlanAcctTitle
acctTitle
:
planAcctTitles
)
{
InvestItem
item
=
ret
.
get
(
acctTitle
.
getRefNo
());
if
(
null
==
item
)
{
item
=
new
InvestItem
();
ret
.
put
(
acctTitle
.
getRefNo
(),
item
);
}
switch
(
acctTitle
.
getTitleType
())
{
case
INVEST_PROFIT:
item
.
intrTitle
=
acctTitle
.
getTitleNo
();
break
;
case
PRIOR_INVESTED:
case
SECND_INVESTED:
case
INVESTED:
item
.
investTitle
=
acctTitle
.
getTitleNo
();
break
;
case
FEE:
item
.
feeTitle
=
acctTitle
.
getTitleNo
();
break
;
}
}
return
ret
;
}
/**
* 资产特征分布
* @param report
* @param accountDate
*/
private
void
buildCommonStat
(
WkManagerReport
report
,
Date
accountDate
)
{
CommonPropStatGroup
commonPropStatGroup
=
new
CommonPropStatGroup
();
report
.
setCommonPropStat
(
commonPropStatGroup
);
// 资产合同金额特征
CommonPropStat
wkm001
=
new
CommonPropStat
();
commonPropStatGroup
.
getCommonPropStat
().
put
(
WkManReportFields
.
WKM001
.
getCode
(),
wkm001
);
//资产余额特征
CommonPropStat
wkm002
=
new
CommonPropStat
();
commonPropStatGroup
.
getCommonPropStat
().
put
(
WkManReportFields
.
WKM002
.
getCode
(),
wkm002
);
// 资产利率特征
CommonPropStat
wkm003
=
new
CommonPropStat
();
commonPropStatGroup
.
getCommonPropStat
().
put
(
WkManReportFields
.
WKM003
.
getCode
(),
wkm003
);
// 合同期限特征
CommonPropStat
wkm004
=
new
CommonPropStat
();
commonPropStatGroup
.
getCommonPropStat
().
put
(
WkManReportFields
.
WKM004
.
getCode
(),
wkm004
);
// 剩余期限特征
CommonPropStat
wkm005
=
new
CommonPropStat
();
commonPropStatGroup
.
getCommonPropStat
().
put
(
WkManReportFields
.
WKM005
.
getCode
(),
wkm005
);
// 账龄特征
CommonPropStat
wkm006
=
new
CommonPropStat
();
commonPropStatGroup
.
getCommonPropStat
().
put
(
WkManReportFields
.
WKM006
.
getCode
(),
wkm006
);
PropDisbStat
propDisbStat
=
loanBakDAO
.
statDisb
(
accountDate
,
report
.
getPlanNo
());
if
(
propDisbStat
!=
null
)
{
wkm001
.
setMin
(
getStatAmt
(
propDisbStat
.
getMinContAmt
()));
wkm001
.
setMax
(
getStatAmt
(
propDisbStat
.
getMaxContAmt
()));
wkm001
.
setAvg
(
getStatAmt
(
propDisbStat
.
getAvgContAmt
()));
wkm002
.
setMin
(
getStatAmt
(
propDisbStat
.
getMinBal
()));
wkm002
.
setMax
(
getStatAmt
(
propDisbStat
.
getMaxBal
()));
wkm002
.
setAvg
(
getStatAmt
(
propDisbStat
.
getAvgBal
()));
wkm003
.
setMin
(
propDisbStat
.
getMinRate
());
wkm003
.
setMax
(
propDisbStat
.
getMaxRate
());
wkm003
.
setAvg
(
propDisbStat
.
getAvgRate
());
wkm003
.
setwAvg
(
propDisbStat
.
getWavgRate
());
wkm004
.
setMin
(
new
BigDecimal
(
propDisbStat
.
getMinContPeriod
()));
wkm004
.
setMax
(
new
BigDecimal
(
propDisbStat
.
getMaxContPeriod
()));
wkm004
.
setAvg
(
propDisbStat
.
getAvgContPeriod
());
wkm004
.
setwAvg
(
propDisbStat
.
getWavgContPeriod
());
wkm005
.
setMin
(
new
BigDecimal
(
propDisbStat
.
getMinRemPeriod
()));
wkm005
.
setMax
(
new
BigDecimal
(
propDisbStat
.
getMaxRemPeriod
()));
wkm005
.
setAvg
(
propDisbStat
.
getAvgRemPeriod
());
wkm005
.
setwAvg
(
propDisbStat
.
getWavgRemPeriod
());
wkm006
.
setMin
(
new
BigDecimal
(
propDisbStat
.
getMinAcctPeriod
()));
wkm006
.
setMax
(
new
BigDecimal
(
propDisbStat
.
getMaxAcctPeriod
()));
wkm006
.
setAvg
(
propDisbStat
.
getAvgAcctPeriod
());
wkm006
.
setwAvg
(
propDisbStat
.
getWavgAcctPeriod
());
}
}
private
void
buildPropCntStat
(
WkManagerReport
report
,
Date
accountDate
)
{
AmtPropCntGroup
amtPropCntGroup
=
new
AmtPropCntGroup
();
report
.
setPropCnt
(
amtPropCntGroup
);
List
<
AmtPropCnt
>
locAmtProp
=
Lists
.
newArrayList
();
List
<
AmtPropCnt
>
ageAmtProp
=
Lists
.
newArrayList
();
List
<
AmtPropCnt
>
genAmtProp
=
Lists
.
newArrayList
();
/**
ReportField WKM007 = new ReportField("WKM007", "性别");
ReportField WKM008 = new ReportField("WKM008", "年龄");
ReportField WKM009 = new ReportField("WKM009", "地区");
*/
amtPropCntGroup
.
getPropCntMap
().
put
(
WkManReportFields
.
WKM007
.
getCode
(),
genAmtProp
);
amtPropCntGroup
.
getPropCntMap
().
put
(
WkManReportFields
.
WKM008
.
getCode
(),
ageAmtProp
);
amtPropCntGroup
.
getPropCntMap
().
put
(
WkManReportFields
.
WKM009
.
getCode
(),
locAmtProp
);
List
<
PropCntStat
>
ageStat
=
loanBakDAO
.
statAge
(
accountDate
,
report
.
getPlanNo
());
List
<
PropCntStat
>
locStat
=
loanBakDAO
.
statLocation
(
accountDate
,
report
.
getPlanNo
());
List
<
PropCntStat
>
genStat
=
loanBakDAO
.
statGender
(
accountDate
,
report
.
getPlanNo
());
// 性别
AmtPropCnt
maleProp
=
new
AmtPropCnt
();
AmtPropCnt
femaleProp
=
new
AmtPropCnt
();
genAmtProp
.
add
(
maleProp
);
genAmtProp
.
add
(
femaleProp
);
Map
<
String
,
PropCntStat
>
genStatMap
=
genStat
.
stream
()
.
collect
(
Collectors
.
toMap
(
PropCntStat:
:
getPropVal
,
item
->
item
));
PropCntStat
maleStat
=
genStatMap
.
get
(
"male"
);
PropCntStat
femaleStat
=
genStatMap
.
get
(
"female"
);
maleProp
.
setCnt
(
getPropCntStatCnt
(
maleStat
));
maleProp
.
setPrin
(
getPropCntStatAmt
(
maleStat
));
femaleProp
.
setCnt
(
getPropCntStatCnt
(
femaleStat
));
femaleProp
.
setPrin
(
getPropCntStatAmt
(
femaleStat
));
// 年龄
for
(
Integer
age
:
AGE_SPLIT
)
{
ageAmtProp
.
add
(
new
AmtPropCnt
());
}
ageAmtProp
.
add
(
new
AmtPropCnt
());
for
(
PropCntStat
ageCntStat
:
ageStat
)
{
int
age
=
Integer
.
parseInt
(
ageCntStat
.
getPropVal
());
int
i
=
0
;
AmtPropCnt
curProp
=
null
;
for
(;
i
<
AGE_SPLIT
.
size
();
i
++)
{
if
(
age
<=
AGE_SPLIT
.
get
(
i
))
{
curProp
=
ageAmtProp
.
get
(
i
);
break
;
}
}
if
(
i
==
AGE_SPLIT
.
size
())
{
curProp
=
ageAmtProp
.
get
(
i
);
}
curProp
.
setCnt
(
curProp
.
getCnt
().
add
(
getPropCntStatCnt
(
ageCntStat
)));
curProp
.
setPrin
(
curProp
.
getPrin
().
add
(
getPropCntStatAmt
(
ageCntStat
)));
}
// 地区
for
(
int
i
=
0
;
i
<
LOC_CNT
;
i
++)
{
AmtPropCnt
locProp
=
new
AmtPropCnt
();
locAmtProp
.
add
(
locProp
);
if
(
i
<
locStat
.
size
())
{
PropCntStat
propStat
=
locStat
.
get
(
i
);
String
provinceCode
=
propStat
.
getPropVal
();
String
province
=
IdcardUtil
.
getProvinceByIdCard
(
provinceCode
+
"1234567890123456"
);
if
(
StringUtils
.
isBlank
(
province
))
{
province
=
propStat
.
getPropVal
();
}
locProp
.
setPropVal
(
province
);
locProp
.
setCnt
(
getPropCntStatCnt
(
propStat
));
locProp
.
setPrin
(
getPropCntStatAmt
(
propStat
));
}
}
}
private
BigDecimal
getStatAmt
(
Money
money
)
{
if
(
null
==
money
)
{
return
BigDecimal
.
ZERO
;
}
else
{
return
money
.
getAmount
();
}
}
private
BigDecimal
getPropCntStatCnt
(
PropCntStat
propCntStat
)
{
if
(
null
==
propCntStat
)
{
return
BigDecimal
.
ZERO
;
}
else
{
return
new
BigDecimal
(
propCntStat
.
getCnt
());
}
}
private
BigDecimal
getPropCntStatAmt
(
PropCntStat
propCntStat
)
{
if
(
null
==
propCntStat
)
{
return
BigDecimal
.
ZERO
;
}
else
{
return
propCntStat
.
getAmt
().
getAmount
();
}
}
private
class
InvestItem
{
String
investTitle
;
String
intrTitle
;
String
feeTitle
;
}
private
class
AcctAmt
{
/**
*
*/
BigDecimal
amt
=
BigDecimal
.
ZERO
;
/**
*
*/
BigDecimal
vtaxAmt
=
BigDecimal
.
ZERO
;
}
private
class
AcctLogKey
extends
BaseEntity
{
/**
* 科目编号
*/
String
titleNo
;
/**
* 事件类型
*/
EventCodeEnum
eventCode
;
public
AcctLogKey
(
String
titleNo
,
EventCodeEnum
eventCode
)
{
this
.
titleNo
=
titleNo
;
this
.
eventCode
=
eventCode
;
}
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/ConfigRefreshJob.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
org.quartz.Job
;
import
org.quartz.PersistJobDataAfterExecution
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.cloud.endpoint.event.RefreshEvent
;
import
org.springframework.context.ConfigurableApplicationContext
;
import
org.springframework.stereotype.Component
;
/**
* 每五分钟刷新配置
* @author bangis.wangdf
* @version com.abssqr.plat.biz.shared.scheduler.job: ConfigRefreshJob.java, v 0.1 2019-08-29 18:06 bangis.wangdf Exp $
*/
@Component
@PersistJobDataAfterExecution
public
class
ConfigRefreshJob
extends
BaseQuartzJob
implements
Job
{
@Autowired
private
ConfigurableApplicationContext
context
;
@Override
public
void
doExecute
()
{
//context.publishEvent(new RefreshEvent("refresh","refresh","刷新配置"));
}
@Override
protected
String
getCronExpr
()
{
return
"0 0/5 * * * ?"
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/ast/AutoBackJob.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
.
ast
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
com.abssqr.plat.common.dal.mysql.auto.dataobject.AstPackDO
;
import
com.abssqr.plat.common.facade.enums.AccountAttributeEnum
;
import
com.abssqr.plat.common.facade.enums.AccountTypeEnum
;
import
com.abssqr.plat.common.facade.enums.AstPackStatusEnum
;
import
com.abssqr.plat.common.facade.enums.AstPackTradeTypeEnum
;
import
com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.PlanCapitalTransTypeEnum
;
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.model.convertor.PacKConvert
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.domain.task.TrCtrTask
;
import
com.abssqr.plat.common.model.repo.ast.PackRepository
;
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.PlanCapitalOrderRepo
;
import
com.abssqr.plat.common.model.repo.task.CommonTaskRepository
;
import
com.abssqr.plat.common.model.repo.tr.TrCtrTaskRepo
;
import
com.abssqr.plat.common.util.base.autoconfig.AbsConfig
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.acct.AcctManager
;
import
com.abssqr.plat.core.service.ast.AstPackManager
;
import
com.abssqr.plat.core.service.util.CommonTaskUtil
;
import
com.general.system.common.model.Money
;
import
com.general.system.common.util.LogUtil
;
import
com.google.common.collect.Lists
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.quartz.DisallowConcurrentExecution
;
import
org.quartz.PersistJobDataAfterExecution
;
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
;
/**
* 自动回购
*
* @author bangis.wangdf
* @version com.abssqr.plat.biz.shared.scheduler.job.ast: AutoBackJob.java, v 0.1 2020-03-03 01:49 bangis.wangdf Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public
class
AutoBackJob
extends
BaseQuartzJob
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
AutoBackJob
.
class
);
@Autowired
PackRepository
packRepository
;
@Autowired
CommonTaskRepository
commonTaskRepository
;
@Autowired
TrCtrTaskRepo
trCtrTaskRepo
;
@Autowired
AstPackManager
astPackManager
;
@Autowired
PlanClearingLogRepo
planClearingLogRepo
;
@Autowired
PlanClearingOrderRepo
planClearingOrderRepo
;
@Autowired
PlanCapitalOrderRepo
planCapitalOrderRepo
;
@Autowired
AcctManager
acctManager
;
@Autowired
AbsConfig
absConfig
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
@Override
protected
String
getCronExpr
()
{
return
"0 1/5 * * * ?"
;
}
public
static
final
String
ORG_CODE
=
"WKXT"
;
public
static
final
Money
reserveAmt
=
new
Money
(
"2000000"
);
@Override
protected
void
doExecute
()
{
// 获取转让会计日
Date
curDate
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
List
<
CommonTask
>
commonTasks
=
commonTaskRepository
.
selectUnifinishTaskByType
(
CommonTaskTypeEnum
.
BUY_BACK_MATCH
);
//没有未完成的回购任务
if
(
CollectionUtils
.
isNotEmpty
(
commonTasks
))
{
LogUtil
.
info
(
LOGGER
,
"AutoBackJob 不执行,存在待回购的 commonTask"
);
return
;
}
// 获取所有回购pack
List
<
AstPackDO
>
astPackDOS
=
packRepository
.
selectPackByStatus
(
curDate
,
AstPackStatusEnum
.
WAIT
,
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
if
(
CollectionUtils
.
isEmpty
(
astPackDOS
))
{
LogUtil
.
info
(
LOGGER
,
"AutoBackJob 不执行,没有待回购包"
);
return
;
}
List
<
TrCtrTask
>
activeBkCtrTasks
=
trCtrTaskRepo
.
getByManagerOrgCode
(
ORG_CODE
,
curDate
,
TaskStatusEnum
.
INIT
,
AstPackTradeTypeEnum
.
BUY_BACK_BIZ
);
if
(
CollectionUtils
.
isNotEmpty
(
activeBkCtrTasks
))
{
LogUtil
.
info
(
LOGGER
,
"AutoBackJob 不执行,存在待回购的TrTask"
);
return
;
}
//清算,结算,支付
Long
clearingLogCnt
=
planClearingLogRepo
.
cntInitClearingLog
(
TransCodeEnum
.
BUY_BACK_OUT
);
Long
clearingOrderCnt
=
planClearingOrderRepo
.
cntInitClearingOrder
(
TransCodeEnum
.
BUY_BACK_OUT
);
Long
activeCnt
=
planCapitalOrderRepo
.
getActiveCntByType
(
PlanCapitalTransTypeEnum
.
NT_BUY_BACK
);
if
(
clearingLogCnt
+
clearingOrderCnt
+
activeCnt
>
0
)
{
LogUtil
.
info
(
LOGGER
,
"AutoBackJob 不执行,支付未完成"
);
return
;
}
//判断账户余额是否满足
AstPackDO
astPackDO
=
astPackDOS
.
get
(
0
);
Money
backAvalAmt
=
Money
.
createWithCent
(
astPackDO
.
getAvalAmt
());
// 1、获取计划对应资金账户 平台虚拟户
List
<
Account
>
accounts
=
acctManager
.
getAcctByPlanNoAndType
(
astPackDO
.
getPlanNo
(),
AccountTypeEnum
.
PLAT_VIRTUAL
,
true
);
Money
bankBal
=
new
Money
();
if
(
CollectionUtils
.
isNotEmpty
(
accounts
))
{
for
(
Account
account
:
accounts
)
{
if
(
account
.
getActAttr
()
==
AccountAttributeEnum
.
PAY
)
{
bankBal
=
account
.
getBankBal
();
}
}
}
//银行余额 - 回购金额 - 预留金额 > 0
if
(
bankBal
.
subtract
(
backAvalAmt
).
subtract
(
reserveAmt
).
isGreaterThanZero
())
{
//开启本次回购
CommonTask
commonTask
=
CommonTaskUtil
.
buildCommonTaskWithContext
(
astPackDO
.
getPackCode
(),
CommonTaskTypeEnum
.
BUY_BACK_MATCH
,
astPackDO
.
getPackCode
());
commonTaskRepository
.
create
(
commonTask
);
packRepository
.
updatePackStatus
(
Lists
.
newArrayList
(
PacKConvert
.
do2Domain
(
astPackDO
)),
AstPackStatusEnum
.
INIT
,
AstPackStatusEnum
.
WAIT
);
}
else
{
LogUtil
.
info
(
LOGGER
,
"AutoBackJob 不执行,账户余额-[{0}]小于 筛选包金额[{1}] + 预留金额[{2}]"
,
bankBal
,
backAvalAmt
,
reserveAmt
);
}
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/ast/ZLFinSerFeeJob.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2018 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
.
ast
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.PlanTranScreenRelDAO
;
import
com.abssqr.plat.common.facade.enums.SyncTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.facade.model.plan.PlanAcctTitle
;
import
com.abssqr.plat.common.model.domain.plan.PlanAcctTitleTransDetail
;
import
com.abssqr.plat.common.model.domain.task.ctr.AstSyncTaskCtr
;
import
com.abssqr.plat.common.model.domain.task.ctr.AstSyncTaskCtrLog
;
import
com.abssqr.plat.common.model.enums.OrgCodeEnum
;
import
com.abssqr.plat.common.model.repo.loanTrans.LoanAstProfitLogRepo
;
import
com.abssqr.plat.common.model.repo.loanTrans.LoanInstalLogRepository
;
import
com.abssqr.plat.common.model.repo.plan.PlanAcctTitleRepo
;
import
com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo
;
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.abssqr.plat.core.service.plan.PlanAcctTitleManager
;
import
com.abssqr.plat.core.service.plan.PlanSettleManager
;
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.StringUtil
;
import
com.general.system.common.util.VarChecker
;
import
com.google.common.collect.Lists
;
import
org.apache.commons.collections.CollectionUtils
;
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
;
import
java.util.Set
;
/**
* 招联金融服务费
*
* @author bangis.wangdf
* @version $Id: PlanAstStatJob.java, v 0.1 2018-01-06 上午12:39 Exp $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public
class
ZLFinSerFeeJob
extends
BaseQuartzJob
{
@Autowired
HostManager
hostManager
;
@Autowired
AstSyncTaskCtrRepo
astSyncTaskCtrRepo
;
@Autowired
LoanInstalLogRepository
loanInstalLogRepository
;
@Autowired
LoanAstProfitLogRepo
loanAstProfitLogRepo
;
@Autowired
TransactionTemplate
transactionTemplate
;
@Autowired
PlanTranScreenRelDAO
planTranScreenRelDAO
;
@Autowired
PlanAcctTitleRepo
planAcctTitleRepo
;
@Autowired
PlanAcctTitleManager
planAcctTitleManager
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
//20191128 前所有金融服务费 查询instalLog,之后instalLog仅获取11条无法支持数据的金融服务费分摊
private
static
Date
FEE_OFFSET_DAY
=
DateTimeUtil
.
parseFromYMD
(
"20191127"
);
/**
* 每天 0 1/5 * * * ?
*/
@Value
(
"${sync.quartz.ast.ser.fee}"
)
private
String
cron
;
@Value
(
"${wkabs.astsync.zhaolian:1009}"
)
private
String
zlOrgCode
;
@Override
protected
String
getCronExpr
()
{
return
cron
;
}
@Override
public
void
doExecute
()
{
AstSyncTaskCtr
taskCtr
=
astSyncTaskCtrRepo
.
getAstSyncTaskCtr
(
zlOrgCode
);
VarChecker
.
checkNotNull
(
taskCtr
,
"没有匹配的同步控制任务={0}"
,
zlOrgCode
);
OrgCodeEnum
orgCodeEnum
=
OrgCodeEnum
.
getByCode
(
taskCtr
.
getOrgCode
());
VarChecker
.
checkNotNull
(
orgCodeEnum
,
"不匹配的机构编码={0}"
,
taskCtr
.
getOrgCode
());
// 获取当前机构会计日
Day
orgDate
=
orgAcctDayComponent
.
getAstAcctDay
(
orgCodeEnum
);
// 判断对机构会计日的模型同步是否完成
AstSyncTaskCtrLog
astModTask
=
astSyncTaskCtrRepo
.
getTaskLogByOrgDate
(
orgDate
.
getStandardDate
(),
SyncTaskTypeEnum
.
AST_MOD
,
taskCtr
.
getOrgCode
());
if
(
astModTask
!=
null
&&
astModTask
.
getStatus
()
==
TaskStatusEnum
.
SUCCESS
)
{
if
(
astSyncTaskCtrRepo
.
checkCanRun
(
taskCtr
.
getOrgCode
(),
taskCtr
.
getTaskCode
(),
SyncTaskTypeEnum
.
AST_SER_FEE
,
orgDate
.
getStandardDate
()))
{
// Date accountDate = SystemDayUtil.getDay().getYesterday().getStandardDate();
LogUtil
.
info
(
LOGGER
,
"[ZLFinSerFeeJob]-[{0}]招联金融服务费计算start"
,
orgDate
.
getDateString
());
Set
<
String
>
spvPlanNos
=
taskCtr
.
getExtData
().
getSpvPlanNos
();
if
(
CollectionUtils
.
isNotEmpty
(
spvPlanNos
))
{
List
<
PlanAcctTitleTransDetail
>
acctTitleTransDetails
=
Lists
.
newArrayList
();
List
<
String
>
allPlanNos
=
Lists
.
newArrayList
();
allPlanNos
.
addAll
(
spvPlanNos
);
List
<
String
>
planNos
=
planTranScreenRelDAO
.
getPlanNosByManagerOrg
(
taskCtr
.
getOrgCode
());
if
(
CollectionUtils
.
isNotEmpty
(
planNos
))
{
allPlanNos
.
addAll
(
planNos
);
}
//获取所有金融服务费科目
List
<
PlanAcctTitle
>
acctFinFeeTitles
=
planAcctTitleRepo
.
getAcctFinFeeTitles
(
allPlanNos
);
if
(
CollectionUtils
.
isNotEmpty
(
acctFinFeeTitles
))
{
acctFinFeeTitles
.
forEach
(
planAcctTitle
->
{
Date
beginDay
=
planAcctTitle
.
getLastSettleDate
();
VarChecker
.
checkNotNull
(
beginDay
,
"招联金融服务费计算失败,未指定开始统计日期 acctTitle=[{0}]"
,
planAcctTitle
);
if
(
DateTimeUtil
.
calcDayDiff
(
orgDate
.
getStandardDate
(),
beginDay
)
>
0
)
{
LogUtil
.
info
(
LOGGER
,
"[ZLFinSerFeeJob]-[{0}]招联金融服务费计算-beginDay[{1}]"
,
planAcctTitle
,
beginDay
);
List
<
Date
>
calcAccountDates
=
Lists
.
newArrayList
();
// beginDay = DateTimeUtil.addDays(beginDay, 1);
while
(
DateTimeUtil
.
calcDayDiff
(
orgDate
.
getStandardDate
(),
beginDay
)
>
0
)
{
beginDay
=
DateTimeUtil
.
addDays
(
beginDay
,
1
);
calcAccountDates
.
add
(
beginDay
);
}
calcAccountDates
.
sort
(
Date:
:
compareTo
);
calcAccountDates
.
forEach
(
calcAccountDate
->
{
LogUtil
.
info
(
LOGGER
,
"[ZLFinSerFeeJob]-[{0}]招联金融服务费计算-calcAccountDate[{1}]"
,
planAcctTitle
,
calcAccountDate
);
PlanAcctTitleTransDetail
planAcctTitleTransDetail
=
PlanSettleManager
.
buildPlanAcctTitleTransDetail
(
calcAccountDate
,
planAcctTitle
,
true
);
Money
finFeeAmt
=
new
Money
();
if
(
DateTimeUtil
.
isBeforeOnDate
(
FEE_OFFSET_DAY
,
calcAccountDate
)){
if
(
StringUtil
.
equals
(
planAcctTitle
.
getPlanNo
(),
"9805102"
))
{
finFeeAmt
=
loanInstalLogRepository
.
getOrgDistPftApporAmt
(
calcAccountDate
,
planAcctTitle
.
getPlanNo
());
}
Money
newFinFeeAmt
=
loanAstProfitLogRepo
.
getOrgDistPftAmt
(
calcAccountDate
,
planAcctTitle
.
getPlanNo
());
finFeeAmt
.
addTo
(
newFinFeeAmt
);
}
else
{
//2019-11-28之前金融服务费 获取逻辑
finFeeAmt
=
loanInstalLogRepository
.
getOrgDistPftAmt
(
calcAccountDate
,
planAcctTitle
.
getPlanNo
());
}
planAcctTitleTransDetail
.
entry
(
finFeeAmt
.
getAmount
());
planAcctTitleTransDetail
.
setSettleDate
(
calcAccountDate
);
// set afterBal
planAcctTitleTransDetail
.
processBeforeUpdate
();
acctTitleTransDetails
.
add
(
planAcctTitleTransDetail
);
});
}
});
}
// 获取当前转让会计日
Day
trfDate
=
orgAcctDayComponent
.
getTrfAcctDay
();
transactionTemplate
.
execute
(
status
->
{
if
(
CollectionUtils
.
isNotEmpty
(
acctTitleTransDetails
))
{
planAcctTitleManager
.
store
(
acctTitleTransDetails
);
}
astSyncTaskCtrRepo
.
insertSyncLog
(
trfDate
.
getStandardDate
(),
orgDate
,
taskCtr
,
SyncTaskTypeEnum
.
AST_SER_FEE
,
TaskStatusEnum
.
SUCCESS
,
hostManager
.
getHostInfo
().
getHostName
());
return
status
;
});
LogUtil
.
info
(
LOGGER
,
"[ZLFinSerFeeJob]-[{0}]招联金融服务费计算end"
,
orgDate
.
getDateString
());
}
}
else
{
LogUtil
.
info
(
LOGGER
,
"[ZLFinSerFeeJob]-[{0}]招联金融服务费计算-ignore,已执行"
,
taskCtr
.
getOrgCode
());
}
}
else
{
LogUtil
.
info
(
LOGGER
,
"[ZLFinSerFeeJob]-[{0}]招联金融服务费计算-ignore,AST_MOD未完成"
,
taskCtr
.
getOrgCode
());
}
}
public
void
setZlOrgCode
(
String
zlOrgCode
)
{
this
.
zlOrgCode
=
zlOrgCode
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/capitalAssertMatch/CapitalAssertMatchJob.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
.
capitalAssertMatch
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.PlanTypeEnum
;
import
com.abssqr.plat.common.facade.enums.SyncTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
import
com.abssqr.plat.common.facade.model.org.OrganizationEntity
;
import
com.abssqr.plat.common.facade.model.plan.Plan
;
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.PlanBase
;
import
com.abssqr.plat.common.model.domain.job.JobControl
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.domain.task.ctr.AstSyncTaskCtrLog
;
import
com.abssqr.plat.common.model.enums.OrgCodeEnum
;
import
com.abssqr.plat.common.model.enums.OrgTypeEnum
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
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.PlanRepo
;
import
com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo
;
import
com.abssqr.plat.common.model.repo.task.CommonTaskRepository
;
import
com.abssqr.plat.common.util.base.autoconfig.AbsConfig
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.plan.PlanManager
;
import
com.general.system.common.model.Money
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.LogUtil
;
import
org.apache.commons.collections.CollectionUtils
;
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
java.util.Date
;
import
java.util.List
;
import
java.util.stream.Collectors
;
/**
* 资金资产解绑任务生成。顺序,解绑->解绑匹配->同步匹配
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public
class
CapitalAssertMatchJob
extends
BaseQuartzJob
{
@Autowired
PlanRepo
planRepo
;
@Autowired
PlanAllocRepo
planAllocRepo
;
@Autowired
CommonTaskRepository
commonTaskRepository
;
@Autowired
JobControlRepository
jobControlRepository
;
@Autowired
AstSyncTaskCtrRepo
astSyncTaskCtrRepo
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
/**
* 间隔1分钟执行生成匹配和解绑任务
*/
@Value
(
"${sync.quartz.plan.capitalAssertMatch}"
)
private
String
cron
;
@Autowired
private
AbsConfig
absConfig
;
@Autowired
private
PlanAcctTitleRepo
planAcctTitleRepo
;
@Override
protected
String
getCronExpr
()
{
return
cron
;
}
@Override
public
void
doExecute
()
{
JobControl
jobControl
=
jobControlRepository
.
lockByJobName
(
getJobName
());
if
(
jobControl
==
null
||
jobControl
.
getIsEff
()
==
YNEnum
.
N
)
{
return
;
}
LogUtil
.
info
(
LOGGER
,
"[capitalAssetMatchJob] 生成资金资产解绑/匹配任务开始"
);
Date
execDate
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
List
<
PlanBase
>
plans
=
planRepo
.
getAllPlanAstByType
(
PlanTypeEnum
.
SPV
.
getCode
());
for
(
PlanBase
planBase
:
plans
)
{
if
(
planBase
.
getPlanType
()
==
PlanTypeEnum
.
SPV
)
{
OrganizationEntity
plan
=
(
OrganizationEntity
)
planRepo
.
getPlanByNo
(
planBase
.
getPlanNo
());
String
planNo
=
plan
.
getPlanNo
();
List
<
CommonTask
>
initAndExecCommonTasks
=
commonTaskRepository
.
queryInitAndExecUnMatchOrMatchTaskByContext
(
planNo
);
if
(
CollectionUtils
.
isNotEmpty
(
initAndExecCommonTasks
))
{
LogUtil
.
info
(
LOGGER
,
"[capitalAssetMatchJob]计划[{1}] 存在[初始化/正在执行中]的[资产匹配/解绑任务任务]"
,
planNo
);
continue
;
}
//查询是否有解绑匹配的Task
List
<
CommonTask
>
initAndIgnoreCommonTask
=
commonTaskRepository
.
queryIgnoreUnMatchOrMatchTaskByContext
(
planNo
);
List
<
CommonTask
>
toMatchedCapticalTask
=
initAndIgnoreCommonTask
.
stream
()
.
filter
(
v
->
v
.
getTaskType
()
==
CommonTaskTypeEnum
.
UNMATCH_CAPTITALASSERT_MATCH
)
.
collect
(
Collectors
.
toList
());
if
(
CollectionUtils
.
isNotEmpty
(
toMatchedCapticalTask
))
{
CommonTask
commonTask
=
toMatchedCapticalTask
.
get
(
0
);
commonTaskRepository
.
updateIgnoreTaskStatus2Init
(
commonTask
.
getId
());
LogUtil
.
info
(
LOGGER
,
"[capitalAssetMatchJob]计划[{1}] 存在状态为Ignore的解绑匹配任务[{2}]"
,
planNo
,
commonTask
.
getBizNo
());
continue
;
}
//查询存在已审批通过未解绑的兑付计划
List
<
PlanAlloc
>
planAllocs
=
planAllocRepo
.
queryUnMatchedApprovedAlloc
(
planNo
);
if
(
CollectionUtils
.
isNotEmpty
(
planAllocs
))
{
PlanAlloc
planAlloc
=
planAllocs
.
get
(
0
);
LogUtil
.
info
(
LOGGER
,
"[capitalAssetMatchJob]计划[{1}] 存在已审批通过的兑付计划[{2}]"
,
planNo
,
planAlloc
.
getAllocNo
());
//生成解绑任务
CommonTask
commonTask
=
buildUnMatchTask
(
planAlloc
.
getAllocNo
(),
planNo
);
commonTaskRepository
.
create
(
commonTask
);
continue
;
}
//判断今日的模型转换是否已经完成
AstSyncTaskCtrLog
lastTaskLog
=
astSyncTaskCtrRepo
.
getTaskLogByExecDate
(
execDate
,
SyncTaskTypeEnum
.
AST_MOD
,
plan
.
getManagerOrgCode
());
if
(
lastTaskLog
!=
null
)
{
String
syncMatchBizNo
=
generateSyncMatchBizNo
(
CommonTaskTypeEnum
.
SYNC_CAPTITALASSERT_MATCH
,
execDate
,
planNo
);
//查询今日是否已经生成了同步匹配任务
List
<
CommonTask
>
commonTasks
=
commonTaskRepository
.
queryByBizNo
(
syncMatchBizNo
);
if
(
CollectionUtils
.
isNotEmpty
(
commonTasks
))
{
continue
;
}
//如果投资结构本机余额是0则不创建匹配任务
if
(
checkCanBuildMatchJob
(
planNo
))
{
LogUtil
.
info
(
LOGGER
,
"[capitalAssetMatchJob]计划[{1}]生成同步匹配任务"
,
planNo
);
CommonTask
commonTask
=
buildSyncMatchTask
(
syncMatchBizNo
,
planNo
);
commonTaskRepository
.
create
(
commonTask
);
}
}
}
}
LogUtil
.
info
(
LOGGER
,
"[capitalAssetMatchJob] 生成资金资产解绑/匹配任务结束"
);
}
private
boolean
checkCanBuildMatchJob
(
String
planNo
)
{
// 获取本金科目
List
<
PlanAcctTitle
>
planAcctTitleList
=
planAcctTitleRepo
.
getByEntityNo
(
planNo
);
Money
totalMoney
=
new
Money
();
for
(
PlanAcctTitle
planAcctTitle
:
planAcctTitleList
)
{
if
(
planAcctTitle
.
getTitleType
().
isInvest
())
{
Money
money
=
planAcctTitle
.
getBal
().
clone
();
totalMoney
.
addTo
(
money
);
}
}
if
(!
totalMoney
.
isGreaterThanZero
())
{
LOGGER
.
info
(
"计划[{0}]投资结构本金总额小于等于0不进行资金资产匹配任务"
,
planNo
);
return
false
;
}
return
true
;
}
private
String
generateSyncMatchBizNo
(
CommonTaskTypeEnum
commonTaskTypeEnum
,
Date
acctDate
,
String
planNo
)
{
StringBuilder
sb
=
new
StringBuilder
();
sb
.
append
(
commonTaskTypeEnum
.
getCode
());
sb
.
append
(
"-"
);
sb
.
append
(
planNo
);
sb
.
append
(
"-"
);
sb
.
append
(
DateTimeUtil
.
formatYMD
(
acctDate
));
return
sb
.
toString
();
}
private
CommonTask
buildUnMatchTask
(
String
bizNo
,
String
planNo
)
{
CommonTask
commonTask
=
buildBasicCommonTask
(
CommonTaskTypeEnum
.
CAPTITALASSERT_UNMATCH
,
planNo
);
commonTask
.
setBizNo
(
bizNo
);
return
commonTask
;
}
private
CommonTask
buildSyncMatchTask
(
String
bizNo
,
String
planNo
)
{
CommonTask
commonTask
=
buildBasicCommonTask
(
CommonTaskTypeEnum
.
SYNC_CAPTITALASSERT_MATCH
,
planNo
);
commonTask
.
setBizNo
(
bizNo
);
return
commonTask
;
}
private
CommonTask
buildBasicCommonTask
(
CommonTaskTypeEnum
planTaskTypeEnum
,
String
planNo
)
{
CommonTask
commonTask
=
new
CommonTask
();
commonTask
.
setContext
(
planNo
);
commonTask
.
setTaskType
(
planTaskTypeEnum
);
commonTask
.
setTaskStatus
(
TaskStatusEnum
.
INIT
);
commonTask
.
setEnv
(
absConfig
.
getEnv
());
commonTask
.
setExecTimes
(
0L
);
return
commonTask
;
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/keeper/node/CapitalAstMatchKeeper.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
.
keeper
.
node
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
import
com.abssqr.plat.common.facade.enums.AbssqrNoticeTypeEnum
;
import
com.abssqr.plat.common.facade.enums.CommonTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.PlanTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.model.domain.plan.PlanTaskLog
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
import
com.abssqr.plat.common.model.repo.plan.PlanTaskLogRepo
;
import
com.abssqr.plat.common.model.repo.task.CommonTaskRepository
;
import
com.general.system.common.model.IEnum
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.MessageUtil
;
import
com.general.system.common.util.SystemDateUtil
;
import
com.google.common.collect.Lists
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.apache.commons.lang3.StringUtils
;
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.Set
;
/**
* 资金资产匹配监控
*
* @author xiachenxiang
* @version com.abssqr.plat.biz.shared.scheduler.job.keeper.node: AstMatchKeeper.java, v 0.1 2020-02-07 1:47 PM xiachenxiang Exp $
*/
@Component
public
class
CapitalAstMatchKeeper
extends
AbstractKeeperNode
{
@Autowired
private
CommonTaskRepository
commonTaskRepository
;
@Autowired
private
PlanTaskLogRepo
planTaskLogRepo
;
@Value
(
"${wkabs.org.zhaolian:1009}"
)
private
String
zhaolianOrgCode
;
@Value
(
"${wkabs.zhaolian.capitalAstMatchKeeper.deadline:10 0 0}"
)
private
String
deadline
;
private
Long
second
=
60L
*
60L
;
@Override
protected
Void
doHandle
(
Date
date
)
{
Date
sysday
=
orgAcctDayComponent
.
getTrfAcctDay
().
getStandardDate
();
// 判断当前时间是否大于10点
Date
currentTime
=
getCurrentStanderDate
();
Date
deadlineTime
=
getDeadLineTime
(
currentTime
,
deadline
);
if
(
currentTime
.
compareTo
(
deadlineTime
)
>
0
)
{
List
<
PlanTaskLog
>
tasks
=
planTaskLogRepo
.
getTasks
(
sysday
,
PlanTaskTypeEnum
.
CAP_AST_MATCH_KEEPER
);
if
(
CollectionUtils
.
isEmpty
(
tasks
))
{
LogUtil
.
info
(
LOGGER
,
"资金资产匹配监控 - start"
);
StringBuffer
sb
=
new
StringBuffer
();
exec
(
sb
,
CommonTaskTypeEnum
.
SYNC_CAPTITALASSERT_MATCH
);
exec
(
sb
,
CommonTaskTypeEnum
.
UNMATCH_CAPTITALASSERT_MATCH
);
exec
(
sb
,
CommonTaskTypeEnum
.
CAPTITALASSERT_UNMATCH
);
if
(
StringUtils
.
isNotEmpty
(
sb
))
{
// 获取用户
LogUtil
.
info
(
LOGGER
,
sb
.
toString
());
// 获取用户
Set
<
String
>
receivers
=
super
.
getAdminReceivers
();
sendSystemNotice
(
"资金资产匹配监控告警"
,
zhaolianOrgCode
,
sb
.
toString
(),
receivers
);
}
PlanTaskLog
planTaskLog
=
new
PlanTaskLog
();
planTaskLog
.
setExecDate
(
sysday
);
planTaskLog
.
setPlanNo
(
zhaolianOrgCode
);
planTaskLog
.
setTaskType
(
PlanTaskTypeEnum
.
CAP_AST_MATCH_KEEPER
);
planTaskLogRepo
.
createTask
(
planTaskLog
);
LogUtil
.
info
(
LOGGER
,
"资金资产匹配监控 - end"
);
}
}
return
null
;
}
/**
* @param sb 提示消息
* @param typeEnum 任务类型
*/
private
void
exec
(
StringBuffer
sb
,
CommonTaskTypeEnum
typeEnum
)
{
// 判断是否存在失败的任务
List
<
CommonTask
>
commonTasks
=
commonTaskRepository
.
queryByTypesAndStatus
(
Lists
.
newArrayList
(
typeEnum
.
getCode
()),
Lists
.
newArrayList
(
TaskStatusEnum
.
FAILURE
.
getCode
()));
if
(
CollectionUtils
.
isNotEmpty
(
commonTasks
))
{
sb
.
append
(
MessageUtil
.
formatMsg
(
"[{0}]存在{1}条失败任务\n"
,
typeEnum
.
getDesc
(),
commonTasks
.
size
()));
}
// 判断执行时间大于1小时
Long
count
=
commonTaskRepository
.
countByTypesAndStatusAndRange
(
second
,
Lists
.
newArrayList
(
typeEnum
.
getCode
()),
Lists
.
newArrayList
(
TaskStatusEnum
.
EXECUTING
.
getCode
()));
if
(
count
.
intValue
()
!=
0
)
{
sb
.
append
(
MessageUtil
.
formatMsg
(
"[{0}]存在{1}条执行超时任务\n"
,
typeEnum
.
getDesc
(),
count
));
}
// 判断执行次数大于1
count
=
commonTaskRepository
.
countUnFinishAndMultipleExecByTypes
(
Lists
.
newArrayList
(
typeEnum
.
getCode
()));
if
(
count
.
intValue
()
!=
0
)
{
sb
.
append
(
MessageUtil
.
formatMsg
(
"[{0}]存在{1}条执行次数大于1的任务\n"
,
typeEnum
.
getDesc
(),
count
));
}
}
@Override
protected
IEnum
getBizType
()
{
return
AbssqrNoticeTypeEnum
.
CapitalAstMatch
;
}
@Override
protected
String
getWatchJob
()
{
return
CapitalAssertMatchJob
.
class
.
getName
();
}
}
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/plan/PlanDailyJob.java
View file @
1e6b317f
...
@@ -4,13 +4,16 @@
...
@@ -4,13 +4,16 @@
*/
*/
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
.
plan
;
package
com
.
abssqr
.
plat
.
biz
.
shared
.
scheduler
.
job
.
plan
;
import
com.abssqr.plat.biz.shared.handler.PlanCashFrozenHandler
;
import
java.util.Date
;
import
java.util.List
;
import
com.abssqr.plat.biz.shared.handler.PlanSettleHandler
;
import
com.abssqr.plat.biz.shared.handler.PlanSettleHandler
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
com.abssqr.plat.common.facade.enums.PlanStatusEnum
;
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.PlanBase
;
import
com.abssqr.plat.common.model.repo.plan.PlanRepo
;
import
com.abssqr.plat.common.model.repo.plan.PlanRepo
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.general.system.bpm.enums.ApproveStatusEnum
;
import
com.general.system.bpm.enums.ApproveStatusEnum
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.LogUtil
;
...
@@ -28,9 +31,6 @@ import org.springframework.transaction.TransactionStatus;
...
@@ -28,9 +31,6 @@ import org.springframework.transaction.TransactionStatus;
import
org.springframework.transaction.support.TransactionCallbackWithoutResult
;
import
org.springframework.transaction.support.TransactionCallbackWithoutResult
;
import
org.springframework.transaction.support.TransactionTemplate
;
import
org.springframework.transaction.support.TransactionTemplate
;
import
java.util.Date
;
import
java.util.List
;
/**
/**
* 计划资产需求统计任务
* 计划资产需求统计任务
*
*
...
@@ -46,8 +46,6 @@ public class PlanDailyJob extends BaseQuartzJob {
...
@@ -46,8 +46,6 @@ public class PlanDailyJob extends BaseQuartzJob {
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanDailyJob
.
class
);
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanDailyJob
.
class
);
@Autowired
@Autowired
private
PlanCashFrozenHandler
planCashFrozenHandler
;
@Autowired
private
PlanSettleHandler
planSettleHandler
;
private
PlanSettleHandler
planSettleHandler
;
@Autowired
@Autowired
private
TransactionTemplate
transactionTemplate
;
private
TransactionTemplate
transactionTemplate
;
...
@@ -149,8 +147,6 @@ public class PlanDailyJob extends BaseQuartzJob {
...
@@ -149,8 +147,6 @@ public class PlanDailyJob extends BaseQuartzJob {
// 结息
// 结息
planSettleHandler
.
execute
(
planEntity
,
curDate
);
planSettleHandler
.
execute
(
planEntity
,
curDate
);
// 水位冻结
planCashFrozenHandler
.
execute
(
planEntity
,
curDate
);
}
}
}
}
}
}
\ No newline at end of file
app/biz/shared/src/main/java/com/abssqr/plat/biz/shared/scheduler/job/plan/PlanPackJob.java
deleted
100644 → 0
View file @
da9236e7
/**
* 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.PlanAstReqHandler
;
import
com.abssqr.plat.biz.shared.scheduler.BaseQuartzJob
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.PlanTranScreenRelDAO
;
import
com.abssqr.plat.common.facade.enums.AstPackStatusEnum
;
import
com.abssqr.plat.common.facade.enums.AstPackTradeTypeEnum
;
import
com.abssqr.plat.common.facade.enums.PlanTypeEnum
;
import
com.abssqr.plat.common.facade.enums.SyncTaskTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TaskStatusEnum
;
import
com.abssqr.plat.common.facade.model.plan.PlanBase
;
import
com.abssqr.plat.common.facade.model.plan.PlanTransferRule
;
import
com.abssqr.plat.common.model.domain.ast.Pack
;
import
com.abssqr.plat.common.model.domain.task.TrCtrTask
;
import
com.abssqr.plat.common.model.repo.ast.PackRepository
;
import
com.abssqr.plat.common.model.repo.plan.PlanRepo
;
import
com.abssqr.plat.common.model.repo.task.AstSyncTaskCtrRepo
;
import
com.abssqr.plat.common.model.repo.tr.TrCtrTaskRepo
;
import
com.abssqr.plat.core.service.accounting.OrgAcctDayComponent
;
import
com.abssqr.plat.core.service.ast.AstPackManager
;
import
com.abssqr.plat.core.service.plan.PlanManager
;
import
com.abssqr.plat.core.service.plan.PlanTransferRuleManager
;
import
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.DateTimeUtil.BetweenType
;
import
com.general.system.common.util.LogUtil
;
import
com.general.system.common.util.VarChecker
;
import
com.google.common.collect.Lists
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.quartz.DisallowConcurrentExecution
;
import
org.quartz.PersistJobDataAfterExecution
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
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.List
;
/**
* 计划资产需求统计任务
*
* @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 $
*/
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
@Component
public
class
PlanPackJob
extends
BaseQuartzJob
{
private
final
static
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
PlanPackJob
.
class
);
@Autowired
AstSyncTaskCtrRepo
astSyncTaskCtrRepo
;
@Autowired
TransactionTemplate
transactionTemplate
;
@Autowired
PlanAstReqHandler
planAstReqHandler
;
@Autowired
PlanTranScreenRelDAO
planTranScreenRelDAO
;
@Autowired
PlanManager
planManager
;
@Autowired
PlanRepo
planRepo
;
@Autowired
PackRepository
packRepository
;
@Autowired
TrCtrTaskRepo
trCtrTaskRepo
;
@Autowired
AstPackManager
astPackManager
;
@Autowired
private
PlanTransferRuleManager
planTransferRuleManager
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
/**
* 每天 0 0/5 * * * ?
*/
@Value
(
"${sync.quartz.plan.pack}"
)
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
,
"[PlanPackJob]-[{0}]计划资产包任务start"
,
curDate
);
List
<
String
>
orgCodes
=
astSyncTaskCtrRepo
.
getLastStatusFinishedOrgCodes
(
curDate
,
SyncTaskTypeEnum
.
AST_MOD
);
for
(
String
orgCode
:
orgCodes
)
{
LogUtil
.
info
(
LOGGER
,
"[PlanPackJob]-[{0}]执行管理机构[{1}]相关的计划资产包生成"
,
curDate
,
orgCode
);
try
{
List
<
TrCtrTask
>
activeTrCtrTasks
=
trCtrTaskRepo
.
getByManagerOrgCode
(
orgCode
,
curDate
,
TaskStatusEnum
.
INIT
,
AstPackTradeTypeEnum
.
AST_TRF_BIZ
);
List
<
Pack
>
activePacks
=
astPackManager
.
getByManagerOrgCode
(
orgCode
,
curDate
,
AstPackStatusEnum
.
INIT
);
if
(
CollectionUtils
.
isNotEmpty
(
activeTrCtrTasks
)
||
CollectionUtils
.
isNotEmpty
(
activePacks
))
{
LogUtil
.
warn
(
LOGGER
,
"[PlanPackJob]-[{0}]执行管理机构[{1}]资产包生成,有执行中的资产包[{2}]或者转让任务[{3}]"
,
curDate
,
orgCode
,
activePacks
.
size
(),
activeTrCtrTasks
.
size
());
continue
;
}
List
<
String
>
planNos
=
planTranScreenRelDAO
.
getPlanNosByManagerOrg
(
orgCode
);
List
<
Pack
>
packs
=
Lists
.
newArrayList
();
for
(
String
planNo
:
planNos
)
{
// 获取计划全量信息
PlanBase
planBase
=
planRepo
.
getPlanByNo
(
planNo
);
// 放款池跳出不生成资产包
if
(
planBase
.
getPlanType
()
==
PlanTypeEnum
.
SPV
)
{
LogUtil
.
debug
(
LOGGER
,
"[PlanPackJob]-跳过放款计划[{0}]"
,
planBase
.
getPlanNo
());
continue
;
}
// 对应转让规则 及 筛选规则
PlanTransferRule
transferRule
=
planTransferRuleManager
.
getByPlanNo
(
planNo
);
VarChecker
.
checkNotNull
(
transferRule
,
"计划[{0}]创建资产包找不到对应转让规则"
,
planBase
.
getPlanNo
());
boolean
trCheck
=
DateTimeUtil
.
between
(
curDate
,
transferRule
.
getStartTrDate
(),
transferRule
.
getStopTrDate
(),
BetweenType
.
se
);
if
(
trCheck
)
{
// 构建资产包
Pack
pack
=
planAstReqHandler
.
execute
(
planBase
,
transferRule
,
curDate
);
if
(
null
!=
pack
)
{
packs
.
add
(
pack
);
}
}
}
transactionTemplate
.
execute
(
new
TransactionCallbackWithoutResult
()
{
@Override
protected
void
doInTransactionWithoutResult
(
TransactionStatus
status
)
{
for
(
Pack
pack
:
packs
)
{
LogUtil
.
info
(
LOGGER
,
"[PlanPackJob]-[{0}]生成资产包[{1}]"
,
curDate
,
pack
);
packRepository
.
create
(
pack
);
}
}
});
}
catch
(
Throwable
e
)
{
LogUtil
.
error
(
LOGGER
,
e
,
"[PlanPackJob]-[{0}]执行管理机构[{1}]相关的计划资产包异常"
,
curDate
,
orgCode
);
}
}
LogUtil
.
info
(
LOGGER
,
"[PlanPackJob]-[{0}]计划资产包任务End"
,
curDate
);
}
}
\ No newline at end of file
app/common/facade/src/main/java/com/abssqr/plat/common/facade/service/report/ReportService.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package
com
.
abssqr
.
plat
.
common
.
facade
.
service
.
report
;
import
com.abssqr.plat.common.facade.model.report.PlanReport
;
import
com.abssqr.plat.common.facade.model.report.wk.WkManagerReport
;
import
com.abssqr.plat.common.facade.param.base.CommonPlanQryParam
;
import
com.abssqr.plat.common.facade.param.reportForm.ReportFormAstParam
;
import
com.abssqr.plat.common.facade.param.reportForm.ReportFormMgrParam
;
import
java.util.List
;
/**
*
* @author yangcheng
* @version ReportService.java, v0.12019-07-0114:18 yangchengExp$
*/
public
interface
ReportService
{
/**
* 计划报表查询
* @param param
* @return
*/
WkManagerReport
getReportFormPlan
(
ReportFormMgrParam
param
);
/**
* 资产报表查询
* @param param
* @return
*/
List
<
PlanReport
>
getReportFormAst
(
ReportFormAstParam
param
);
/**
* 资产报表查询
* @param param
* @return
*/
List
<
PlanReport
>
getReportFormMonthEnd
(
CommonPlanQryParam
param
);
}
app/test/src/test/java/com/abssqr/plat/test/BaseAutoTests.java
View file @
1e6b317f
...
@@ -6,27 +6,20 @@ package com.abssqr.plat.test;
...
@@ -6,27 +6,20 @@ package com.abssqr.plat.test;
import
java.util.Date
;
import
java.util.Date
;
import
com.abssqr.plat.biz.shared.handler.LoanAstBuyBackMatchHandler
;
import
com.abssqr.plat.biz.shared.scheduler.job.keeper.node.CapitalAstMatchKeeper
;
import
com.abssqr.plat.common.dal.mysql.auto.dao.AcctDateDAO
;
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.dal.sync.auto.dao.WkAbsMfsBillCtrDAO
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
import
com.abssqr.plat.common.model.domain.accounting.AcctDate
;
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.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.enums.OrgCodeEnum
;
import
com.abssqr.plat.common.model.repo.acct.AcctDateRepo
;
import
com.abssqr.plat.common.model.repo.acct.AcctDateRepo
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.date.DateUtil
;
import
com.general.system.common.util.DateTimeUtil
;
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.common.util.VarChecker
;
import
org.apache.commons.lang3.StringUtils
;
import
org.mockito.Mockito
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener
;
import
org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener
;
import
org.springframework.boot.test.mock.mockito.SpyBean
;
import
org.springframework.test.context.TestExecutionListeners
;
import
org.springframework.test.context.TestExecutionListeners
;
/**
/**
...
@@ -39,34 +32,11 @@ import org.springframework.test.context.TestExecutionListeners;
...
@@ -39,34 +32,11 @@ import org.springframework.test.context.TestExecutionListeners;
@TestExecutionListeners
(
listeners
=
MockitoTestExecutionListener
.
class
)
@TestExecutionListeners
(
listeners
=
MockitoTestExecutionListener
.
class
)
public
class
BaseAutoTests
extends
BaseAutoWithOutMockTests
{
public
class
BaseAutoTests
extends
BaseAutoWithOutMockTests
{
// @MockBean
// protected JobControlRepository mockJobControlRepository;
//
//
// @BeforeMethod
// protected void stopJob(){
// JobControl jobControl = new JobControl();
// jobControl.setIsEff(YNEnum.N);
// when(mockJobControlRepository.selectByJobName(Mockito.anyString())).thenReturn(jobControl);
// when(mockJobControlRepository.lockByJobName(Mockito.anyString())).thenReturn(jobControl);
// }
//
// protected void mockJobEff(String jobName,YNEnum ynEnum){
// JobControl jobControl = new JobControl();
// jobControl.setIsEff(ynEnum);
// jobControl.setJobName(jobName);
// when(mockJobControlRepository.selectByJobName(jobName)).thenReturn(jobControl);
// when(mockJobControlRepository.lockByJobName(jobName)).thenReturn(jobControl);
// }
@Autowired
@Autowired
private
WkAbsMfsBillCtrDAO
wkAbsMfsBillCtrDAO
;
private
WkAbsMfsBillCtrDAO
wkAbsMfsBillCtrDAO
;
@Autowired
@Autowired
private
AcctDateDAO
acctDateDAO
;
private
AcctDateDAO
acctDateDAO
;
@Autowired
@Autowired
private
AcctDateRepo
acctDateRepo
;
private
AcctDateRepo
acctDateRepo
;
...
@@ -79,17 +49,18 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
...
@@ -79,17 +49,18 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
Date
acctDate
=
DateUtil
.
parse
(
strDate
);
Date
acctDate
=
DateUtil
.
parse
(
strDate
);
this
.
updateDate
(
acctDate
,
orgCode
);
this
.
updateDate
(
acctDate
,
orgCode
);
}
}
protected
void
updateDate
(
Date
acctDate
,
String
orgCode
)
{
protected
void
updateDate
(
Date
acctDate
,
String
orgCode
)
{
OrgCodeEnum
org
=
OrgCodeEnum
.
getByCode
(
orgCode
);
OrgCodeEnum
org
=
OrgCodeEnum
.
getByCode
(
orgCode
);
VarChecker
.
checkNotNull
(
org
,
"不匹配的机构编码={0}"
,
orgCode
);
VarChecker
.
checkNotNull
(
org
,
"不匹配的机构编码={0}"
,
orgCode
);
AcctDate
now
=
acctDateRepo
.
getAcctDate
(
org
);
AcctDate
now
=
acctDateRepo
.
getAcctDate
(
org
);
if
(
now
==
null
){
if
(
now
==
null
)
{
now
=
new
AcctDate
();
now
=
new
AcctDate
();
now
.
setOrgCode
(
org
);
now
.
setOrgCode
(
org
);
now
.
setAcctDate
(
acctDate
);
now
.
setAcctDate
(
acctDate
);
now
.
setEff
(
true
);
now
.
setEff
(
true
);
acctDateRepo
.
addAcctDate
(
now
);
acctDateRepo
.
addAcctDate
(
now
);
}
else
if
(!
DateTimeUtil
.
isSameDay
(
now
.
getAcctDate
(),
acctDate
))
{
}
else
if
(!
DateTimeUtil
.
isSameDay
(
now
.
getAcctDate
(),
acctDate
))
{
now
.
setAcctDate
(
acctDate
);
now
.
setAcctDate
(
acctDate
);
acctDateRepo
.
modifyAcctDate
(
now
);
acctDateRepo
.
modifyAcctDate
(
now
);
}
}
...
@@ -100,6 +71,7 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
...
@@ -100,6 +71,7 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
/**
/**
* 停止任务
* 停止任务
*
* @param jobName
* @param jobName
* @return
* @return
*/
*/
...
@@ -120,6 +92,7 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
...
@@ -120,6 +92,7 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
/**
/**
* 开启任务
* 开启任务
*
* @param jobName
* @param jobName
*/
*/
protected
void
validJobCtr
(
String
jobName
)
{
protected
void
validJobCtr
(
String
jobName
)
{
...
@@ -138,40 +111,4 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
...
@@ -138,40 +111,4 @@ public class BaseAutoTests extends BaseAutoWithOutMockTests {
jobControlRepository
.
update
(
jobControl
);
jobControlRepository
.
update
(
jobControl
);
}
}
@SpyBean
private
CapitalAstMatchKeeper
capitalAstMatchKeeper
;
protected
void
mockCapitalAstMatchKeeper
(
Date
date
)
{
Mockito
.
doReturn
(
date
).
when
(
capitalAstMatchKeeper
).
getCurrentStanderDate
();
}
@SpyBean
private
LoanAstBuyBackMatchHandler
loanAstBuyBackMatchHandler
;
protected
void
mockLoanAstBuyBackMatchHandler
(){
Mockito
.
doReturn
(
Boolean
.
TRUE
).
when
(
loanAstBuyBackMatchHandler
).
canRun
();
}
protected
void
mockCurrentDate
(
Date
date
){
SystemDateUtil
systemDateUtil
=
Mockito
.
mock
(
SystemDateUtil
.
class
);
final
Date
date1
=
Mockito
.
mock
(
Date
.
class
);
Mockito
.
when
(
date1
.
getTime
()).
thenReturn
(
date
.
getTime
());
// Mockito.
//Mockito.when(systemDateUtil).thenReturn(date);
//Mockito.doReturn(date).when(systemDateUtil);
}
protected
void
autoPartition
(
String
orgCode
)
{
AstSyncTaskCtr
astSyncTaskCtr
=
new
AstSyncTaskCtr
();
astSyncTaskCtr
.
setOrgCode
(
orgCode
);
String
partitionName
=
"BILL_CTR_"
+
astSyncTaskCtr
.
getOrgCode
();
String
pName
=
wkAbsMfsBillCtrDAO
.
queryPartitionForCheck
(
partitionName
);
if
(
StringUtils
.
isBlank
(
pName
)){
wkAbsMfsBillCtrDAO
.
updateCreatePartition
(
astSyncTaskCtr
.
getOrgCode
(),
partitionName
);
}
}
}
}
app/test/src/test/java/com/abssqr/plat/test/testlink/ast/ZLFinSerFeeJobTest.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2019 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
test
.
testlink
.
ast
;
import
com.abssqr.plat.biz.shared.scheduler.job.ast.ZLFinSerFeeJob
;
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
;
/**
* @author bangis.wangdf
* @version com.abssqr.plat.test.testlink.ast: ZLFinSerFeeJobTest.java, v 0.1 2019-09-17 18:43 bangis.wangdf Exp $
*/
public
class
ZLFinSerFeeJobTest
extends
BaseAutoTests
{
@Autowired
ZLFinSerFeeJob
zlFinSerFeeJob
;
@XTest
(
relatePath
=
"testlink/ast/finFee"
)
@Test
(
dataProvider
=
"YamlDataProvider"
,
description
=
"金融服务费处理"
)
public
void
testFinSerFee
(
ICase
iCase
,
String
acctDate
)
{
try
{
super
.
updateDate
(
acctDate
,
OrgCodeEnum
.
WK1009
.
getCode
());
zlFinSerFeeJob
.
setZlOrgCode
(
"1009"
);
zlFinSerFeeJob
.
doExecute
();
}
catch
(
Exception
e
){
e
.
printStackTrace
();
}
finally
{
// 校验数据
super
.
checkDB
(
iCase
);
super
.
clearDB
(
iCase
);
}
}
}
app/test/src/test/java/com/abssqr/plat/test/unittest/capitalAstMatch/CapitalAstMatchUnitTest.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
test
.
unittest
.
capitalAstMatch
;
import
com.abssqr.plat.biz.shared.handler.CapitalAstMatchHandler
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
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
com.general.system.common.util.DateTimeUtil
;
import
com.general.system.common.util.VarChecker
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.testng.annotations.Test
;
import
java.util.Date
;
/**
* 资金资产匹配测试
* @author xiachenxiang
* @version com.abssqr.plat.test.unittest.capitalAstMatch: CapitalAstMatchUnitTest.java, v 0.1 2020-02-04 6:21 PM xiachenxiang Exp $
*/
public
class
CapitalAstMatchUnitTest
extends
BaseAutoTests
{
@Autowired
private
CapitalAssertMatchJob
capitalAssertMatchJob
;
@Autowired
private
CapitalAstMatchHandler
capitalAstMatchHandler
;
@XTest
(
relatePath
=
"unittest/capitalAstMatch/astMatch"
)
@Test
(
dataProvider
=
"YamlDataProvider"
,
description
=
"资金资产匹配"
)
public
void
exec
(
ICase
iCase
,
String
planNo
,
String
execDateString
,
String
acctDay
,
boolean
expectResult
,
boolean
expectExp
)
{
super
.
validJobCtr
(
capitalAssertMatchJob
.
getJobName
());
try
{
Date
execDate
=
DateTimeUtil
.
parseFromYMD
(
execDateString
);
super
.
updateDate
(
acctDay
,
OrgCodeEnum
.
ABS
.
getCode
());
boolean
result
=
capitalAstMatchHandler
.
execute
(
planNo
,
execDate
);
VarChecker
.
checkEquals
(
result
,
expectResult
,
"实际结果与期望不符"
);
}
catch
(
Exception
e
){
if
(!
expectExp
){
e
.
printStackTrace
();
throw
e
;
}
}
finally
{
// 校验数据
super
.
checkDB
(
iCase
);
super
.
clearDB
(
iCase
);
}
}
}
app/test/src/test/java/com/abssqr/plat/test/unittest/capitalAstUnMatch/CapitalAstUnMatchTest.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
test
.
unittest
.
capitalAstUnMatch
;
import
com.abssqr.plat.biz.shared.handler.CapitalAstUnMatchHandler
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
import
com.abssqr.plat.common.dal.mysql.auto.resultmap.AstScale
;
import
com.abssqr.plat.common.model.enums.OrgCodeEnum
;
import
com.abssqr.plat.common.model.repo.ast.LoanBakRepo
;
import
com.abssqr.plat.test.BaseAutoTests
;
import
com.abssqr.test.annotation.XTest
;
import
com.abssqr.test.icase.ICase
;
import
com.general.system.common.model.Money
;
import
com.general.system.common.util.DateTimeUtil
;
import
org.apache.shiro.util.Assert
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.testng.annotations.Test
;
import
java.math.BigDecimal
;
import
java.util.Date
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
public
class
CapitalAstUnMatchTest
extends
BaseAutoTests
{
@Autowired
CapitalAstUnMatchHandler
capitalAstUnMatchHandler
;
@Autowired
LoanBakRepo
loanBakRepo
;
@Autowired
private
CapitalAssertMatchJob
capitalAssertMatchJob
;
@XTest
(
relatePath
=
"unittest/capitalAstUnMatch"
)
@Test
(
dataProvider
=
"YamlDataProvider"
,
description
=
"资金资产解绑"
)
public
void
exec
(
ICase
iCase
,
String
planNo
,
String
allocNo
,
String
acctDay
,
String
layerNo
,
Integer
allOwnCapital
)
{
super
.
validJobCtr
(
capitalAssertMatchJob
.
getJobName
());
try
{
Date
acctDate
=
DateTimeUtil
.
parseFromYMD
(
acctDay
);
super
.
updateDate
(
acctDate
,
OrgCodeEnum
.
ABS
.
getCode
());
capitalAstUnMatchHandler
.
execute
(
planNo
,
allocNo
,
acctDate
);
List
<
AstScale
>
astScaleList
=
loanBakRepo
.
getAstScale
(
acctDate
,
planNo
);
Map
<
String
,
List
<
AstScale
>>
capitalAstMap
=
astScaleList
.
stream
()
.
collect
(
Collectors
.
groupingBy
(
AstScale:
:
getCapitalNo
));
List
<
AstScale
>
astScales
=
capitalAstMap
.
get
(
layerNo
);
Assert
.
notEmpty
(
astScales
,
"找不到投资层级"
+
layerNo
+
"对应的资产"
);
Money
prinBal
=
astScales
.
get
(
0
).
getPrinBal
();
Assert
.
isTrue
(
prinBal
.
getAmount
().
compareTo
(
new
BigDecimal
(
allOwnCapital
))<=
0
,
"不符合预期资产规模"
);
}
catch
(
Exception
e
){
e
.
printStackTrace
();
throw
e
;
}
finally
{
// 校验数据
super
.
checkDB
(
iCase
);
super
.
clearDB
(
iCase
);
}
}
}
app/test/src/test/java/com/abssqr/plat/test/unittest/job/CapitalAssertMatchJobTest.java
deleted
100644 → 0
View file @
da9236e7
package
com
.
abssqr
.
plat
.
test
.
unittest
.
job
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
import
com.abssqr.plat.common.facade.enums.YNEnum
;
import
com.abssqr.plat.common.model.domain.job.JobControl
;
import
com.abssqr.plat.common.model.enums.OrgCodeEnum
;
import
com.abssqr.plat.common.model.repo.job.JobControlRepository
;
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
;
/*
前置条件: 不存在Init或者exec的任务
情况一,存在为Ignore的解绑匹配任务
情况二,存在已审批通过未解绑兑付计划
情况三,今日模型转换已完成且未生成同步匹配任务
*/
public
class
CapitalAssertMatchJobTest
extends
BaseAutoTests
{
@Autowired
private
CapitalAssertMatchJob
capitalAssertMatchJob
;
@Autowired
private
JobControlRepository
jobControlRepository
;
@XTest
(
relatePath
=
"unittest/job/capitalAssetMatch"
)
@Test
(
dataProvider
=
"YamlDataProvider"
,
description
=
"生成资产解绑和资产资金匹配的任务"
)
public
void
jobTest
(
ICase
iCase
,
String
strDate
)
throws
ParseException
{
try
{
//开启CapitalAssertMatchJob任务
JobControl
jobControl
=
jobControlRepository
.
selectByJobName
(
capitalAssertMatchJob
.
getJobName
());
jobControl
.
setIsEff
(
YNEnum
.
Y
);
jobControlRepository
.
update
(
jobControl
);
// 更新会计日期
super
.
updateDate
(
strDate
,
OrgCodeEnum
.
ABS
.
getCode
());
capitalAssertMatchJob
.
doExecute
();
}
catch
(
Exception
e
){
e
.
printStackTrace
();
throw
e
;
}
finally
{
// 校验数据
super
.
checkDB
(
iCase
);
super
.
clearDB
(
iCase
);
}
}
}
app/test/src/test/java/com/abssqr/plat/test/unittest/job/keeper/CapitalAstMatchKeeperTest.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
test
.
unittest
.
job
.
keeper
;
import
com.abssqr.plat.biz.shared.scheduler.job.capitalAssertMatch.CapitalAssertMatchJob
;
import
com.abssqr.plat.biz.shared.scheduler.job.keeper.node.CapitalAstMatchKeeper
;
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.keeper: CapitalAstMatchKeeperTest.java, v 0.1 2020-02-07 4:59 PM xiachenxiang Exp $
*/
public
class
CapitalAstMatchKeeperTest
extends
BaseAutoTests
{
@Autowired
private
CapitalAstMatchKeeper
capitalAstMatchKeeper
;
@XTest
(
relatePath
=
"unittest/job/CapitalAstMatchKeeper"
)
@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
);
validJobCtr
(
CapitalAssertMatchJob
.
class
.
getName
());
mockCapitalAstMatchKeeper
(
date
);
capitalAstMatchKeeper
.
execute
(
date
);
invalidJobCtr
(
CapitalAssertMatchJob
.
class
.
getName
());
}
catch
(
ParseException
e
)
{
throw
new
RuntimeException
(
e
.
getMessage
());
}
finally
{
// 校验数据
super
.
checkDB
(
iCase
);
super
.
clearDB
(
iCase
);
}
}
}
app/test/src/test/java/com/abssqr/plat/test/unittest/planBuyBack/PlanBuyBackMatchTest.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.com Inc.
* Copyright (c) 2017-2020 All Rights Reserved.
*/
package
com
.
abssqr
.
plat
.
test
.
unittest
.
planBuyBack
;
import
com.abssqr.plat.biz.shared.dispatcher.buyBackMatch.LoanAstBuyBackMatchExecutor
;
import
com.abssqr.plat.biz.shared.dispatcher.buyBackMatch.LoanAstBuyBackMatchLoader
;
import
com.abssqr.plat.biz.shared.dispatcher.buyBackMatch.LoanAstBuyBackMatchStarter
;
import
com.abssqr.plat.common.model.domain.task.CommonTask
;
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.util.List
;
/**
* 资产回购筛选测试
*
* @author xiachenxiang
* @version com.abssqr.plat.test.unittest.planBuyBack: PlanBuyBack.java, v 0.1 2020-02-12 2:10 PM xiachenxiang Exp $
*/
public
class
PlanBuyBackMatchTest
extends
BaseAutoTests
{
@Autowired
private
LoanAstBuyBackMatchLoader
planBuyBackMatchLoader
;
@Autowired
private
LoanAstBuyBackMatchExecutor
planBuyBackMatchExecutor
;
@XTest
(
relatePath
=
"unittest/planBuyBack/match"
)
@Test
(
dataProvider
=
"YamlDataProvider"
,
description
=
"资产回购筛选"
)
public
void
execute
(
ICase
iCase
,
String
acctDate
)
{
try
{
// 更新会计日期
super
.
updateDate
(
acctDate
,
OrgCodeEnum
.
ABS
.
getCode
());
// 设置任务关闭
this
.
invalidJobCtr
(
LoanAstBuyBackMatchStarter
.
JOB_NAME
);
mockLoanAstBuyBackMatchHandler
();
planBuyBackMatchLoader
.
setSleepTime
(
0L
);
List
<
CommonTask
>
commonTasks
=
planBuyBackMatchLoader
.
loadToDoNodes
(
1
);
planBuyBackMatchExecutor
.
execute
(
commonTasks
.
get
(
0
));
}
catch
(
Exception
e
)
{
throw
e
;
}
finally
{
// 校验数据
super
.
checkDB
(
iCase
);
super
.
clearDB
(
iCase
);
}
}
}
app/web/src/main/java/com/abssqr/plat/web/controller/job/JobController.java
View file @
1e6b317f
...
@@ -10,10 +10,7 @@ package com.abssqr.plat.web.controller.job;
...
@@ -10,10 +10,7 @@ package com.abssqr.plat.web.controller.job;
import
java.util.List
;
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.plan.PlanDailyJob
;
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.facade.model.account.Account
;
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.plan.PlanBase
;
import
com.abssqr.plat.common.facade.service.AccountService
;
import
com.abssqr.plat.common.facade.service.AccountService
;
...
@@ -50,30 +47,14 @@ public class JobController {
...
@@ -50,30 +47,14 @@ public class JobController {
@Autowired
@Autowired
private
PlanDailyJob
planDailyJob
;
private
PlanDailyJob
planDailyJob
;
@Autowired
@Autowired
private
PlanPackJob
planPackJob
;
@Autowired
private
ZLFinSerFeeJob
zlFinSerFeeJob
;
@Autowired
private
PlanReportRepo
planReportRepo
;
private
PlanReportRepo
planReportRepo
;
@Autowired
@Autowired
private
AccountService
accountService
;
private
AccountService
accountService
;
@Autowired
@Autowired
private
CapitalAssertMatchJob
capitalAssertMatchJob
;
@Autowired
private
OrgAcctDayComponent
orgAcctDayComponent
;
private
OrgAcctDayComponent
orgAcctDayComponent
;
/**
* 计划资产包生成任务
*
* @return
* @description
*/
@RequestMapping
(
path
=
"/job/planPackJob.json"
,
method
=
RequestMethod
.
GET
)
public
BaseResult
<
Boolean
>
planPackJob
()
{
planPackJob
.
doExecute
();
return
BaseResult
.
success
(
null
);
}
/**
/**
* 每日处理
* 每日处理
...
@@ -92,18 +73,6 @@ public class JobController {
...
@@ -92,18 +73,6 @@ public class JobController {
/**
/**
* 资金资产任务Task生成Job
*
* @return
* @description
*/
@RequestMapping
(
path
=
"/job/capitalAssetMatchJob.json"
,
method
=
RequestMethod
.
GET
)
public
BaseResult
<
Boolean
>
capitalAssetMatchJob
()
{
capitalAssertMatchJob
.
doExecute
();
return
BaseResult
.
success
(
null
);
}
/**
* 查询账户余额
* 查询账户余额
*
*
* @return
* @return
...
@@ -114,17 +83,6 @@ public class JobController {
...
@@ -114,17 +83,6 @@ public class JobController {
return
accountService
.
queryBalance
();
return
accountService
.
queryBalance
();
}
}
/**
* 查询账户余额
*
* @return
* @description
*/
@RequestMapping
(
path
=
"/acct/zlFinSerFeeJob.json"
,
method
=
RequestMethod
.
GET
)
public
BaseResult
<
Boolean
>
zlFinSerFeeJob
()
{
zlFinSerFeeJob
.
doExecute
();
return
BaseResult
.
success
(
null
);
}
/**
/**
* 初始化计划 日报基础数据
* 初始化计划 日报基础数据
...
...
app/web/src/main/java/com/abssqr/plat/web/controller/report/ReportFormController.java
deleted
100644 → 0
View file @
da9236e7
/**
* abssqr.comInc.
* Copyright(c)2019-2019AllRightsReserved.
*/
package
com
.
abssqr
.
plat
.
web
.
controller
.
report
;
import
com.abssqr.plat.common.facade.enums.PlanTypeEnum
;
import
com.abssqr.plat.common.facade.enums.TimeStampTypeEnum
;
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.wk.WkManagerReport
;
import
com.abssqr.plat.common.facade.param.base.CommonPlanQryParam
;
import
com.abssqr.plat.common.facade.param.reportForm.ReportFormAstParam
;
import
com.abssqr.plat.common.facade.param.reportForm.ReportFormMgrParam
;
import
com.abssqr.plat.common.facade.service.report.ReportService
;
import
com.abssqr.plat.common.model.exception.AbssqrBizException
;
import
com.abssqr.plat.web.fileExport.FileExportTypeEnum
;
import
com.abssqr.plat.web.fileExport.FileExportUtil
;
import
com.abssqr.plat.common.facade.utils.ListID
;
import
com.general.system.common.util.MessageUtil
;
import
org.apache.commons.collections.CollectionUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Controller
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
javax.servlet.http.HttpServletResponse
;
import
java.io.IOException
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
/**
* 报表中心
*
* @author yangcheng
* @version ReportFormController.java, v0.12019-06-2819:14 yangchengExp$
*/
@Controller
@RequestMapping
(
value
=
"/export"
)
public
class
ReportFormController
{
@Autowired
private
FileExportUtil
fileExportUtil
;
@Autowired
private
ReportService
reportService
;
/**
* 管理报表
* @param param
* @return
* @description 查询计划报表
*/
@RequestMapping
(
path
=
"/reportForm/plan/months"
,
method
=
RequestMethod
.
GET
)
public
void
getReportFormPlan
(
ReportFormMgrParam
param
,
HttpServletResponse
response
)
throws
IOException
{
FileExportTypeEnum
fileExportType
=
param
.
getPlanType
().
equals
(
PlanTypeEnum
.
SPV
.
getCode
())?
FileExportTypeEnum
.
MANAGER_SPV_RPT
:
FileExportTypeEnum
.
MANAGER_PLAN_RPT
;
WkManagerReport
wkManagerReport
=
reportService
.
getReportFormPlan
(
param
);
String
begin
=
param
.
getBeginTime
();
String
end
=
param
.
getEndTime
();
if
(
wkManagerReport
==
null
)
{
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"计划[{0}]对应日期[{1}-{2}]的报表未生成"
,
param
.
getPlanNo
(),
begin
,
end
));
}
// 报表模型数据
Map
<
String
,
Object
>
model
=
new
HashMap
<>();
String
rptDate
=
param
.
getYear
()
+
TimeStampTypeEnum
.
getByCode
(
param
.
getTimeStamp
()).
getDesc
();
model
.
put
(
"rpt"
,
wkManagerReport
);
model
.
put
(
"rptDate"
,
rptDate
);
model
.
put
(
"investId"
,
new
ListID
());
model
.
put
(
"feeId"
,
new
ListID
());
MonthReportDateField
beginDays
=
new
MonthReportDateField
();
beginDays
.
parse
(
begin
);
MonthReportDateField
endDays
=
new
MonthReportDateField
();
endDays
.
parse
(
end
);
String
fileKey
=
param
.
getPlanNo
()
+
"_"
+
beginDays
.
desc
()
+
"-"
+
endDays
.
desc
();
fileExportUtil
.
exportXls
(
response
,
fileExportType
,
fileKey
,
model
);
}
/**
* 查询资产报表
* @param param
* @return
* @description 查询资产报表
*/
@RequestMapping
(
path
=
"/reportForm/ast/days"
,
method
=
RequestMethod
.
GET
)
public
void
getReportFormPlanAst
(
ReportFormAstParam
param
,
HttpServletResponse
response
)
throws
IOException
{
FileExportTypeEnum
fileExportType
=
param
.
getPlanType
().
equals
(
PlanTypeEnum
.
SPV
.
getCode
())?
FileExportTypeEnum
.
AST_SPV_RPT
:
FileExportTypeEnum
.
AST_PLAN_RPT
;
List
<
PlanReport
>
reports
=
reportService
.
getReportFormAst
(
param
);
if
(
CollectionUtils
.
isEmpty
(
reports
))
{
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"计划[{0}]对应日期[{1}-{2}]的报表未生成"
,
param
.
getPlanNo
(),
param
.
getBeginDate
(),
param
.
getEndDate
()));
}
PlanReport
firstRpt
=
reports
.
get
(
0
);
PlanReport
lastRpt
=
reports
.
get
(
reports
.
size
()
-
1
);
// 报表模型数据
Map
<
String
,
Object
>
model
=
new
HashMap
<>();
model
.
put
(
"reports"
,
reports
);
String
fileKey
=
param
.
getPlanNo
()
+
"_"
+
firstRpt
.
getRptDate
().
desc
()
+
"-"
+
lastRpt
.
getRptDate
().
desc
();
fileExportUtil
.
exportXls
(
response
,
fileExportType
,
fileKey
,
model
);
}
/**
* 受让池资产月末报表
* @param param
* @return
* @description 查询资产报表
*/
@RequestMapping
(
path
=
"/reportForm/ast/monthEnd"
,
method
=
RequestMethod
.
GET
)
public
void
getReportFormAstMonth
(
CommonPlanQryParam
param
,
HttpServletResponse
response
)
throws
IOException
{
List
<
PlanReport
>
reports
=
reportService
.
getReportFormMonthEnd
(
param
);
if
(
CollectionUtils
.
isEmpty
(
reports
))
{
throw
new
AbssqrBizException
(
MessageUtil
.
formatMsg
(
"计划[{0}]月末报表没有生成"
,
param
.
getPlanNo
()));
}
PlanReport
firstRpt
=
reports
.
get
(
0
);
PlanReport
lastRpt
=
reports
.
get
(
reports
.
size
()
-
1
);
// 报表模型数据
Map
<
String
,
Object
>
model
=
new
HashMap
<>();
model
.
put
(
"reports"
,
reports
);
String
fileKey
=
param
.
getPlanNo
()
+
"_"
+
firstRpt
.
getRptDate
().
desc
()
+
"-"
+
lastRpt
.
getRptDate
().
desc
();
fileExportUtil
.
exportXls
(
response
,
FileExportTypeEnum
.
AST_ME_RPT
,
fileKey
,
model
);
}
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment