1 package com.supwisdom.dlpay.api.service.impl
3 import com.supwisdom.dlpay.agent.citizencard.YnrccUtil
4 import com.supwisdom.dlpay.api.bean.YnrccChkfileBean
5 import com.supwisdom.dlpay.api.dao.PersondtlDao
6 import com.supwisdom.dlpay.api.dao.TransactionChkdtlDao
7 import com.supwisdom.dlpay.api.dao.TransactionChkfileDao
8 import com.supwisdom.dlpay.api.dao.TransactionMainDao
9 import com.supwisdom.dlpay.api.domain.TTransactionChkdtl
10 import com.supwisdom.dlpay.api.domain.TTransactionChkfile
11 import com.supwisdom.dlpay.api.service.TransactionReconciliationService
12 import com.supwisdom.dlpay.api.service.TransactionServiceProxy
13 import com.supwisdom.dlpay.exception.TransactionCheckException
14 import com.supwisdom.dlpay.framework.dao.BusinessparaDao
15 import com.supwisdom.dlpay.framework.service.SystemUtilService
16 import com.supwisdom.dlpay.framework.tenant.TenantContext
17 import com.supwisdom.dlpay.framework.util.MoneyUtil
18 import com.supwisdom.dlpay.framework.util.TradeDict
19 import com.supwisdom.dlpay.framework.util.TradeErrorCode
20 import com.supwisdom.dlpay.util.ConstantUtil
21 import org.springframework.beans.factory.annotation.Autowired
22 import org.springframework.stereotype.Service
25 class TransactionReconciliationServiceImpl : TransactionReconciliationService {
27 private lateinit var transactionChkfileDao: TransactionChkfileDao
29 private lateinit var transactionChkdtlDao: TransactionChkdtlDao
31 private lateinit var systemUtilService: SystemUtilService
33 private lateinit var businessparaDao: BusinessparaDao
35 private lateinit var transactionMainDao: TransactionMainDao
37 private lateinit var persondtlDao: PersondtlDao
39 private lateinit var transactionService: TransactionServiceProxy
41 override fun getTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile? {
42 return transactionChkfileDao.getByAccdateAndSourcetype(accdate, sourcetype)
45 override fun doInitTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile {
46 return transactionChkfileDao.getByAccdateAndSourcetype(accdate, sourcetype).let {
48 if (ConstantUtil.CHKFILE_STATUS_INIT != it.status)
49 throw TransactionCheckException(TradeErrorCode.BUSINESS_DEAL_ERROR, "accdate=$accdate,sourcetype=$sourcetype 的chkfile已经存在")
52 saveInitTransactionChkfile(accdate, sourcetype) //保存init对账文件
57 override fun saveOrUpdateTransactionChkfile(chkfile: TTransactionChkfile): TTransactionChkfile {
58 return transactionChkfileDao.save(chkfile)
61 override fun saveYnrccTransactionChkDtl(chkfile: TTransactionChkfile, bean: YnrccChkfileBean): TTransactionChkdtl {
62 return transactionChkdtlDao.save(TTransactionChkdtl().apply {
63 this.chkfileId = chkfile.id
64 this.accdate = chkfile.accdate
65 this.sourcetype = chkfile.sourcetype
66 this.recordno = bean.recordno
67 this.amount = bean.amount / 100.0
68 this.otherRefno = bean.agentrefno
69 this.localRefno = bean.refno
70 this.otherAccdate = bean.agentdate
71 this.transtype = bean.flag
72 this.otherStatus = bean.status
74 this.extdata = bean.summary
75 this.chkresult = ConstantUtil.CHKDTL_CHKRESULT_UNCHECK
77 this.lastsaved = systemUtilService.sysdatetime.sysdate
78 this.tenantid = TenantContext.getTenantSchema()
82 override fun doBatchSaveYnrccTransactionChkDtl(chkfile: TTransactionChkfile, list: ArrayList<YnrccChkfileBean>): Boolean {
84 saveYnrccTransactionChkDtl(chkfile, bean)
89 override fun doSuccessTransactionChkfile(chkfile: TTransactionChkfile, remark: String) {
90 val suminfo = transactionChkdtlDao.getTransactionSumInfo(chkfile.accdate, chkfile.sourcetype)
91 chkfile.status = ConstantUtil.CHKFILE_STATUS_UNCHECK
92 chkfile.remark = remark
93 chkfile.othercnt = suminfo.totalcnt ?: 0
94 chkfile.otheramt = suminfo.totalamt ?: 0.0
95 transactionChkfileDao.save(chkfile)
96 businessparaDao.updateBusinessparaValue(YnrccUtil.YNRCC_BILLS_DOWNLOAD_LASTDATE, chkfile.accdate) //更新下载对账单日期
99 override fun deleteTransactionChkdtls(chkfileId: String) {
100 transactionChkdtlDao.deleteByChkfileid(chkfileId)
103 override fun saveInitTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile {
104 return transactionChkfileDao.save(TTransactionChkfile().apply {
105 this.accdate = accdate
106 this.sourcetype = sourcetype
107 this.status = ConstantUtil.CHKFILE_STATUS_INIT
108 this.result = ConstantUtil.CHKFILE_RESULT_NONE
114 this.lastsaved = systemUtilService.sysdatetime.sysdate
115 this.tenantid = TenantContext.getTenantSchema()
119 override fun doCheckEqualTransdtls(chkfile: TTransactionChkfile) {
121 transactionChkdtlDao.getCheckEqualDetails(chkfile.id)?.forEach { chkdtl ->
122 chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_EQUAL
123 chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_EQUAL
124 chkdtl.remark = "双方交易一致"
125 transactionChkdtlDao.save(chkdtl) //对账明细表更新
127 transactionService.checkSuccessConfirm(chkdtl.localRefno, chkdtl.otherAccdate)
131 override fun getUncheckTransactionChkdtls(chkfileId: String): List<TTransactionChkdtl> {
132 return transactionChkdtlDao.getUncheckTransactionChkdtls(chkfileId) ?: ArrayList<TTransactionChkdtl>(0)
135 override fun doCheckTransactionChkdtl(chkdtl: TTransactionChkdtl) {
136 val transMain = transactionMainDao.findByRefno(chkdtl.localRefno)
138 if (null == transMain || !transMain.person) {
139 chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_NOTEXIST
140 chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP
141 chkdtl.remark = "本地流水不存在"
142 transactionChkdtlDao.save(chkdtl) //对账明细表更新
145 if(!MoneyUtil.moneyEqual(chkdtl.amount,transMain.personDtl.amount)){
146 chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_DIFF
147 chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP
148 chkdtl.remark = "交易金额不相等"
149 transactionChkdtlDao.save(chkdtl) //对账明细表更新
152 if(transMain.accdate!=chkdtl.accdate || transMain.sourceType != chkdtl.sourcetype){
154 chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_ERROR
155 chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP
156 chkdtl.remark = "记账日期或支付方式错误"
157 transactionChkdtlDao.save(chkdtl) //对账明细表更新
160 if (transMain.status == TradeDict.DTL_STATUS_SUCCESS) {
161 chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_EQUAL
162 chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_EQUAL
163 chkdtl.remark = "双方交易一致"
164 transactionChkdtlDao.save(chkdtl) //对账明细表更新
166 transactionService.checkSuccessConfirm(chkdtl.localRefno, chkdtl.otherAccdate)
169 transactionService.repair(transMain.refno, chkdtl.otherAccdate, chkdtl.otherRefno, "补账成功")
171 chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_NOCHARGE
172 chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_EQUAL
173 chkdtl.remark = "本地未入账,补账成功"
174 transactionChkdtlDao.save(chkdtl) //对账明细表更新
178 override fun checkUncheckExists(chkfileId: String): Boolean {
179 return transactionChkdtlDao.getUncheckCount(chkfileId).existed > 0
182 override fun doCheckLocalMoreDtls(chkfile: TTransactionChkfile) {
183 transactionChkdtlDao.findLocalMoreDtls(chkfile.accdate, chkfile.sourcetype, chkfile.id)?.forEach { refno ->
185 transactionMainDao.findByRefno(refno)?.let { transMain ->
186 if (TradeDict.DTL_STATUS_SUCCESS == transMain.status && transMain.accdate == chkfile.accdate && transMain.sourceType == chkfile.sourcetype) {
187 transactionChkdtlDao.save(TTransactionChkdtl().apply {
188 this.chkfileId = chkfile.id
189 this.accdate = chkfile.accdate
190 this.sourcetype = chkfile.sourcetype
192 this.amount = transMain.personDtl.amount
193 this.otherRefno = transMain.reverseRefno ?: "0"
194 this.localRefno = transMain.refno
195 this.otherAccdate = transMain.accdate
196 this.transtype = when (transMain.reverseType) {
198 else -> transMain.reverseType
200 this.otherStatus = "unknown"
201 this.remark = "本地成功流水第三方流水不存在"
202 this.extdata = transMain.personDtl.transdesc
203 this.chkresult = ConstantUtil.CHKDTL_CHKRESULT_NOTEXIST
204 this.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP
205 this.lastsaved = systemUtilService.sysdatetime.sysdate
206 this.tenantid = chkfile.tenantid
213 override fun doConfirmChkfileStatus(chkfile: TTransactionChkfile): TTransactionChkfile {
214 val personSumInfo = persondtlDao.getPersondtlSumInfo(chkfile.accdate, chkfile.sourcetype, chkfile.tenantid)
215 chkfile.localcnt = personSumInfo.totalcnt ?: 0
216 chkfile.localamt = personSumInfo.totalamt ?: 0.00
217 chkfile.status = ConstantUtil.CHKFILE_STATUS_finish //对账结束
218 if (chkfile.othercnt == chkfile.localcnt && MoneyUtil.moneyEqual(chkfile.otheramt, chkfile.localamt)) {
219 //fixme: 是否还需判断chkdtl中resolved是否都equal
220 chkfile.result = ConstantUtil.CHKFILE_RESULT_EQUAL
221 chkfile.remark = "对账完成,双方一致"
223 chkfile.result = ConstantUtil.CHKFILE_RESULT_UNEQUAL
224 chkfile.remark = "对账不平,请查看明细数据"
226 transactionChkfileDao.save(chkfile)