From 88664898def5bd908ee4b3a5ab446858efd1d682 Mon Sep 17 00:00:00 2001 From: Xia Kaixiang Date: Wed, 14 Aug 2019 10:26:52 +0800 Subject: [PATCH] =?utf8?q?=E5=AF=B9=E8=B4=A6=E5=88=9D=E6=AD=A5=E5=AE=9E?= =?utf8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- config/application-devel-pg-xkx.properties | 2 +- .../dlpay/agent/CheckFileProvider.java | 6 +- .../supwisdom/dlpay/api/dao/PersondtlDao.java | 5 + .../dlpay/api/dao/TransactionChkdtlDao.java | 19 ++ .../api/domain/TSourceTypeCheckStatus.java | 22 ++ .../dlpay/api/domain/TTransactionChkdtl.java | 1 + .../supwisdom/dlpay/util/ConstantUtil.java | 4 +- .../service/citizencard_checkfile_service.kt | 260 ++++++++++++++++++ .../dlpay/api/scheduler_sourcetype_chk.kt | 107 +++++-- .../dlpay/api/scheduler_ynrccchk_task.kt | 4 +- .../api/service/impl/account_service_impl.kt | 6 +- ...transaction_reconciliation_service_impl.kt | 159 ++++++++++- .../service/impl/transaction_service_impl.kt | 42 ++- .../transaction_reconciliation_service.kt | 28 +- .../dlpay/api/service/transaction_service.kt | 23 +- 15 files changed, 627 insertions(+), 61 deletions(-) create mode 100644 payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_checkfile_service.kt diff --git a/config/application-devel-pg-xkx.properties b/config/application-devel-pg-xkx.properties index 727f38f1..3c10fe9f 100644 --- a/config/application-devel-pg-xkx.properties +++ b/config/application-devel-pg-xkx.properties @@ -29,7 +29,7 @@ security.request.sign=false shopbalance.updater.cron=- #download.ynrcc.chkfile.cron =3 0/2 * * * ? #query.third.transdtl.result.cron=7 0/1 * * * ? -dayend.settletask.cron=0 0/2 * * * ? +#dayend.settletask.cron=0 0/2 * * * ? ############################################# spring.cloud.consul.enabled=false spring.cloud.consul.host=172.28.201.70 diff --git a/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java b/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java index 88c7f80b..b8b3fa52 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/agent/CheckFileProvider.java @@ -3,9 +3,9 @@ package com.supwisdom.dlpay.agent; import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus; public interface CheckFileProvider { - AgentResponse acquireCheckFile(String checkDate); + AgentResponse acquireCheckFile(TSourceTypeCheckStatus checkStatus); - AgentResponse queryCheckFile(String checkDate); + AgentResponse queryCheckFile(TSourceTypeCheckStatus checkStatus); - AgentResponse downloadCheckFile(String checkDate); + AgentResponse downloadCheckFile(TSourceTypeCheckStatus checkStatus); } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java index f5163738..c04f3f35 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/PersondtlDao.java @@ -1,13 +1,18 @@ package com.supwisdom.dlpay.api.dao; import com.supwisdom.dlpay.api.domain.TPersondtl; +import com.supwisdom.dlpay.framework.data.CountAmountBean; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; @Repository public interface PersondtlDao extends JpaRepository,JpaSpecificationExecutor { Page findByUseridAndStatus(String userid,String status, Pageable pageable); + + @Query("select count(t.refno) as totalcnt,sum(t.amount) as totalamt from TPersondtl t where t.accdate=?1 and t.sourceType=?2 and t.tenantid=?3 ") + CountAmountBean getPersondtlSumInfo(String accdate, String sourcetype, String tenantid); } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionChkdtlDao.java b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionChkdtlDao.java index 18967864..122ce76f 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionChkdtlDao.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/dao/TransactionChkdtlDao.java @@ -1,12 +1,17 @@ package com.supwisdom.dlpay.api.dao; +import com.supwisdom.dlpay.api.domain.TPersondtl; import com.supwisdom.dlpay.api.domain.TTransactionChkdtl; import com.supwisdom.dlpay.framework.data.CountAmountBean; +import com.supwisdom.dlpay.framework.data.ExistBean; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface TransactionChkdtlDao extends JpaRepository { @@ -17,4 +22,18 @@ public interface TransactionChkdtlDao extends JpaRepository getCheckEqualDetails(String chkfileId); + + @Query("from TTransactionChkdtl t where t.chkfileId=?1 and t.chkresult='uncheck' order by t.recordno ") + List getUncheckTransactionChkdtls(String chkfileId); + + @Query("select count(t.id) as existed from TTransactionChkdtl t where t.chkfileId=?1 and t.chkresult='uncheck' ") + ExistBean getUncheckCount(String chkfileId); + + @Query(value = "select t.refno from TB_PERSONDTL t left join TB_TRANSACTION_CHKDTL a on t.REFNO=a.OTHER_REFNO and a.CHKFILE_ID=:chkfileId " + + " where t.ACCDATE=:accdate and t.SOURCETYPE=:sourcetype and t.status='success' and a.id is null order by t.refno ", nativeQuery = true) + List findLocalMoreDtls(@Param("accdate")String accdate, @Param("sourcetype")String sourcetype, @Param("chkfileId") String chkfileId); + } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java index 4a4f41c3..bad55b9e 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TSourceTypeCheckStatus.java @@ -48,6 +48,12 @@ public class TSourceTypeCheckStatus { @NotNull private String tenantId; + @Column(name = "chkfile_url", length = 400) + private String chkfileUrl; + + @Column(name = "remark", length = 600) + private String remark; + public Integer getId() { return id; } @@ -127,4 +133,20 @@ public class TSourceTypeCheckStatus { public void setCheckStatus(Boolean checkStatus) { this.checkStatus = checkStatus; } + + public String getChkfileUrl() { + return chkfileUrl; + } + + public void setChkfileUrl(String chkfileUrl) { + this.chkfileUrl = chkfileUrl; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } } diff --git a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionChkdtl.java b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionChkdtl.java index 422d766a..f5dc80eb 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionChkdtl.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/api/domain/TTransactionChkdtl.java @@ -57,6 +57,7 @@ public class TTransactionChkdtl { @Column(name = "RESOLVED", length = 20) private String resolved; + @Version @Column(name = "LASTSAVED") private Timestamp lastsaved; diff --git a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java index c7b479cf..7d7e8097 100644 --- a/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java +++ b/payapi/src/main/java/com/supwisdom/dlpay/util/ConstantUtil.java @@ -53,9 +53,11 @@ public class ConstantUtil { * 对账明细状态 * */ public static final String CHKDTL_CHKRESULT_UNCHECK= "uncheck"; //未检查 - public static final String CHKDTL_CHKRESULT_NEGATION= "negation"; //交易流水不存在 + public static final String CHKDTL_CHKRESULT_EQUAL= "equal"; //一致 + public static final String CHKDTL_CHKRESULT_NOTEXIST= "notexist"; //交易流水不存在 public static final String CHKDTL_CHKRESULT_NOCHARGE = "nocharge"; //支付未记账 public static final String CHKDTL_CHKRESULT_DIFF = "diff"; //金额不相等 + public static final String CHKDTL_CHKRESULT_ERROR = "error"; //记账日期或支付方式错误 /** * 对账明细解决状态 diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_checkfile_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_checkfile_service.kt new file mode 100644 index 00000000..615db409 --- /dev/null +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/agent/service/citizencard_checkfile_service.kt @@ -0,0 +1,260 @@ +package com.supwisdom.dlpay.agent.service + +import com.sun.jersey.api.client.Client +import com.sun.jersey.api.client.ClientResponse +import com.supwisdom.dlpay.agent.AgentCode +import com.supwisdom.dlpay.agent.AgentResponse +import com.supwisdom.dlpay.agent.CheckFileProvider +import com.supwisdom.dlpay.agent.citizencard.YnrccUtil +import com.supwisdom.dlpay.api.bean.YnrccChkfileBean +import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus +import com.supwisdom.dlpay.api.domain.TTransactionChkfile +import com.supwisdom.dlpay.api.service.SourceTypeService +import com.supwisdom.dlpay.api.service.TransactionReconciliationService +import com.supwisdom.dlpay.exception.TransactionException +import com.supwisdom.dlpay.framework.service.SystemUtilService +import com.supwisdom.dlpay.framework.util.StringUtil +import com.supwisdom.dlpay.framework.util.TradeDict +import com.supwisdom.dlpay.util.ConstantUtil +import mu.KotlinLogging +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.io.BufferedReader +import java.io.InputStream +import java.io.InputStreamReader +import javax.ws.rs.core.MediaType + +@Component("citizenCardCheckFileProvider") +class CitizenCardCheckFileProvider : CheckFileProvider { + @Autowired + private lateinit var systemUtilService: SystemUtilService + @Autowired + private lateinit var transactionReconciliationService: TransactionReconciliationService + @Autowired + private lateinit var citizencardPayService: CitizencardPayService + @Autowired + private lateinit var sourceTypeService: SourceTypeService + + private val logger = KotlinLogging.logger { } + + + override fun acquireCheckFile(checkStatus: TSourceTypeCheckStatus): AgentResponse { + try { + val billDate = checkStatus.checkFileDate + logger.info("大理农商行对账单下载:download checkdate=【$billDate】") + + val chkfile: TTransactionChkfile = transactionReconciliationService.getTransactionChkfile(billDate, checkStatus.sourceType)?.let { file -> + when (file.status) { + ConstantUtil.CHKFILE_STATUS_INIT -> file //初始化直接返回 + ConstantUtil.CHKFILE_STATUS_ERROR, ConstantUtil.CHKFILE_STATUS_UNCHECK -> reinitCheckFile(file) //错误或未对账的直接重新拉取 + else -> { + when (checkStatus.forceRecheck) { + true -> reinitCheckFile(file) //对账已完成但强制重新对账 + false -> throw TransactionException(-1, "大理农商行该天[$billDate]已对账完成") //对账已完成报错 + } + } + } + } ?: transactionReconciliationService.saveInitTransactionChkfile(billDate, checkStatus.sourceType) + + val resp = citizencardPayService.getChkfilename(billDate, null) + when(resp.code) { + YnrccUtil.CODE_SUCCESS -> { + val agentConfig = sourceTypeService.getChargePaytypeConfig(TradeDict.PAYTYPE_CITIZEN_CARD, true) + val agentUrl = agentConfig[YnrccUtil.YNRCC_ANGENT_URL] + "/download?filename=" + resp.filename + + //成功 + return AgentResponse().also { + it.code = AgentCode.SUCCESS + it.agentMsg = "获取对账文件路径成功" + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.chkfileUrl = agentUrl + }) + } + + } + YnrccUtil.NO_RECORDS_TODAY -> { + //当日无交易明细,也创建空记录 + transactionReconciliationService.doSuccessTransactionChkfile(chkfile, "请求银行返回:当日无交易明细") + + //成功 + return AgentResponse().also { + it.code = AgentCode.SUCCESS + it.agentMsg = "当日无交易明细" + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.chkfileUrl = "none" + }) + } + + } + else -> { + //报错,退出对账单拉取 + logger.error("大理农商行对账单下载[$billDate]报错:${resp.message}") + chkfile.status = ConstantUtil.CHKFILE_STATUS_ERROR + chkfile.remark = "请求前置获取对账文件报错:${resp.message}" + transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile) + + //失败 + return AgentResponse().also { + it.code = AgentCode.FAIL + it.agentMsg = chkfile.remark + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.remark = chkfile.remark + }) + } + } + } + } catch (et: TransactionException) { + return AgentResponse().also { + it.code = AgentCode.FAIL + it.agentMsg = et.message + it.agentCode = "${et.code()}" + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.remark = et.message + }) + } + } + } + + override fun queryCheckFile(checkStatus: TSourceTypeCheckStatus): AgentResponse { + return AgentResponse().also { + it.code = AgentCode.SUCCESS + it.agentMsg = "OK" + it.payload = checkStatus + } + } + + override fun downloadCheckFile(checkStatus: TSourceTypeCheckStatus): AgentResponse { + try{ + val billDate = checkStatus.checkFileDate + val agentUrl = checkStatus.chkfileUrl + if ("none" == agentUrl) { + return AgentResponse().also { + it.code = AgentCode.SUCCESS + it.agentMsg = "当日无交易明细" + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.checkFileOk = true + this.remark = "当日无交易明细" + }) + } + } + + val chkfile = transactionReconciliationService.doInitTransactionChkfile(billDate, checkStatus.sourceType) + + //下载对账单数据 + val client = Client.create() + client.setConnectTimeout(30000) + val respClient = client.resource(agentUrl).type(MediaType.APPLICATION_OCTET_STREAM_TYPE).get(ClientResponse::class.java) + if (200 == respClient.status) { + val stream = respClient.getEntity(InputStream::class.java) + BufferedReader(InputStreamReader(stream)).use { reader -> + val header = reader.readLine() + val fields = header.split(",").mapNotNull { if (it.isNotEmpty()) it else null } + val batchSize = 10000 //每次保存的数目 + var failcnt = 0 + + val datalist = ArrayList() + while (true) { + val line = reader.readLine() ?: break + if (line.isEmpty()) continue + val columns = line.split(",").mapNotNull { if (it.isNotEmpty()) it else null } + val bean = YnrccChkfileBean() + StringUtil.transforToBean(fields, columns, bean) + datalist.add(bean) + if (datalist.size >= batchSize) { + val fcnt = doBatchSaveYnrccCheckDetails(chkfile, datalist) //保存 + failcnt += fcnt + datalist.clear() + } + } + //保存最后的不足batchSize的记录 + if (datalist.size > 0) { + val fcnt = doBatchSaveYnrccCheckDetails(chkfile, datalist) //保存 + failcnt += fcnt + } + + if (failcnt > 0) { + //该天对账单保存错误 + chkfile.status = ConstantUtil.CHKFILE_STATUS_ERROR + chkfile.remark = "对账单数据存在保存失败记录,请手动核对对账单数据" + transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile) + + return AgentResponse().also { + it.code = AgentCode.FAIL + it.agentMsg = chkfile.remark + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.remark = chkfile.remark + }) + } + } + + //成功 + transactionReconciliationService.doSuccessTransactionChkfile(chkfile, "对账单数据下载成功") + return AgentResponse().also { + it.code = AgentCode.SUCCESS + it.agentMsg = "[$billDate]日对账数据入库成功" + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.checkFileOk = true + this.remark = "[$billDate]日对账数据入库成功" + }) + } + } + } else { + logger.error("请求前置download[${chkfile.accdate}]对账单返回失败:httpStatus=[${respClient.status}]。获取对账文件数据失败") + chkfile.status = ConstantUtil.CHKFILE_STATUS_ERROR + chkfile.remark = "请求前置获取对账单数据失败,download返回:httpStatus=${respClient.status}" + transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile) + + return AgentResponse().also { + it.code = AgentCode.FAIL + it.agentMsg = chkfile.remark + it.payload = sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus.apply { + this.remark = chkfile.remark + }) + } + } + + }catch (ex:Exception){ + return AgentResponse().also { + it.code = AgentCode.FAIL + it.agentMsg = ex.message?:"按对账单路径获取对账数据入库异常" + it.payload = checkStatus + } + } + } + + private fun reinitCheckFile(chkfile: TTransactionChkfile): TTransactionChkfile { + transactionReconciliationService.deleteTransactionChkdtls(chkfile.id) //删除明细 + return transactionReconciliationService.saveOrUpdateTransactionChkfile(chkfile.apply { + this.status = ConstantUtil.CHKFILE_STATUS_INIT + this.result = ConstantUtil.CHKFILE_RESULT_NONE + this.remark = null + this.othercnt = 0 + this.otheramt = 0.00 + this.localcnt = 0 + this.localamt = 0.00 + }) //初始化chkfile + } + + private fun doBatchSaveYnrccCheckDetails(chkfile: TTransactionChkfile, list: ArrayList): Int { + try { + transactionReconciliationService.doBatchSaveYnrccTransactionChkDtl(chkfile, list) + return 0 //批量保存成功,无失败 + } catch (e1: Exception) { + } + + //批量保存有异常,逐笔保存 + var failcnt = 0 + for (bean in list) { + try { + transactionReconciliationService.saveYnrccTransactionChkDtl(chkfile, bean) + } catch (e2: Exception) { + failcnt++ + e2.printStackTrace() + continue + } + } + return failcnt + } + + +} \ No newline at end of file diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt index 3f895f98..4a552f82 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_sourcetype_chk.kt @@ -5,9 +5,13 @@ import com.supwisdom.dlpay.agent.AgentResponse import com.supwisdom.dlpay.agent.CheckFileProvider import com.supwisdom.dlpay.api.domain.TSourceType import com.supwisdom.dlpay.api.domain.TSourceTypeCheckStatus +import com.supwisdom.dlpay.api.domain.TTransactionChkfile import com.supwisdom.dlpay.api.service.SourceTypeService +import com.supwisdom.dlpay.api.service.TransactionReconciliationService +import com.supwisdom.dlpay.exception.TransactionException import com.supwisdom.dlpay.framework.service.SystemUtilService import com.supwisdom.dlpay.framework.util.DateUtil +import com.supwisdom.dlpay.util.ConstantUtil import mu.KotlinLogging import net.javacrumbs.shedlock.core.SchedulerLock import org.springframework.beans.BeansException @@ -159,6 +163,12 @@ class SourceTypeCheckExecutor { @Autowired private lateinit var applicationContext: ApplicationContext + @Autowired + private lateinit var transactionReconciliationService: TransactionReconciliationService + + @Autowired + private lateinit var sourceTypeService: SourceTypeService + private val logger = KotlinLogging.logger { } private fun getProvider(sourcetype: String): CheckFileProvider? { @@ -171,7 +181,7 @@ class SourceTypeCheckExecutor { } private fun downloadFile(provider: CheckFileProvider, checkStatus: TSourceTypeCheckStatus): ExecutorResult { - return provider.downloadCheckFile(checkStatus.checkFileDate).let { resp -> + return provider.downloadCheckFile(checkStatus).let { resp -> when { resp.code == AgentCode.SUCCESS -> ExecutorResult(resp.payload, SUCCESS, "成功") resp.code == AgentCode.REQUIRE_QUERY -> ExecutorResult(resp.payload, WAIT, "等待查询对账文件") @@ -183,37 +193,86 @@ class SourceTypeCheckExecutor { @Async("sourcetypeCheckTaskExecutor") fun checkAndDownloadChkfile(checkStatus: TSourceTypeCheckStatus): Future { // 2. 根据对账日期下载对账文件 - val result = getProvider(checkStatus.sourceType)?.let { provider -> - val acResp = provider.acquireCheckFile(checkStatus.checkFileDate) - if (acResp.code == AgentCode.REQUIRE_QUERY) { - var success: AgentResponse = - AgentResponse().apply { - code = AgentCode.FAIL + try { + val result = getProvider(checkStatus.sourceType)?.let { provider -> + val acResp = provider.acquireCheckFile(checkStatus) + if (acResp.code == AgentCode.REQUIRE_QUERY) { + var success: AgentResponse = + AgentResponse().apply { + code = AgentCode.FAIL + } + repeat(10) { + if (success.code != AgentCode.SUCCESS) { + Thread.sleep(3000) + success = provider.queryCheckFile(checkStatus) } - repeat(10) { - if (success.code != AgentCode.SUCCESS) { - Thread.sleep(3000) - success = provider.queryCheckFile(checkStatus.checkFileDate) } - } - if (success.code == AgentCode.SUCCESS) { - downloadFile(provider, success.payload) + if (success.code == AgentCode.SUCCESS) { + downloadFile(provider, success.payload) + } else { + ExecutorResult(checkStatus, FAIL, "下载失败,未能查到对账文件") + } + } else if (acResp.code == AgentCode.SUCCESS) { + downloadFile(provider, acResp.payload) } else { - ExecutorResult(checkStatus, FAIL, "下载失败,未能查到对账文件") + ExecutorResult(checkStatus, FAIL, acResp.agentMsg) } - } else if (acResp.code == AgentCode.SUCCESS) { - downloadFile(provider, acResp.payload) - } else { - ExecutorResult(checkStatus, FAIL, acResp.agentMsg) - } - } ?: ExecutorResult(checkStatus, FAIL, "未定义 CheckFileProvider") - return AsyncResult(result) + } ?: ExecutorResult(checkStatus, FAIL, "未定义 CheckFileProvider") + return AsyncResult(result) + } catch (ex: Exception) { + return AsyncResult(ExecutorResult(checkStatus, FAIL, ex.message ?: "下载对账单异常")) + } + } @Async("sourcetypeCheckTaskExecutor") fun reconciliation(checkStatus: TSourceTypeCheckStatus): Future { // 3. 完成对账 - TODO("实现对账逻辑") -// return AsyncResult(ExecutorResult(checkStatus, SUCCESS, "成功")) + val result = transactionReconciliationService.getTransactionChkfile(checkStatus.checkAccdate, checkStatus.sourceType)?.let { chkfile -> + if (ConstantUtil.CHKFILE_STATUS_UNCHECK == chkfile.status) { + //TODO:"实现对账逻辑" + try { + when (doCheckProcess(chkfile).result) { + ConstantUtil.CHKFILE_RESULT_EQUAL -> { + checkStatus.checkStatus = true //对账成功 + sourceTypeService.saveOrUpdateSourceTypeCheckStatus(checkStatus) + ExecutorResult(checkStatus, SUCCESS, "对账成功,双方一致") + } + else -> ExecutorResult(checkStatus, FAIL, "对账不平") + } + } catch (ex: Exception) { + ex.printStackTrace() + ExecutorResult(checkStatus, FAIL, "对账异常") + } + } else { + ExecutorResult(checkStatus, FAIL, "[${checkStatus.checkAccdate}]日入库的checkfile状态异常[${chkfile.status}]") + } + } ?: ExecutorResult(checkStatus, FAIL, "未找到[${checkStatus.checkAccdate}]日入库的对账数据") + return AsyncResult(result) + } + + fun doCheckProcess(chkfile: TTransactionChkfile): TTransactionChkfile { + try { + //统一处理交易一致的记录 + transactionReconciliationService.doCheckEqualTransdtls(chkfile) + } catch (e1: Exception) { + } + + //剩余的不平记录逐一对比 + transactionReconciliationService.getUncheckTransactionChkdtls(chkfile.id).forEach { + transactionReconciliationService.doCheckTransactionChkdtl(it) + } + + //判断chkdtl是否全部对账完成 + if (transactionReconciliationService.checkUncheckExists(chkfile.id)) { + throw TransactionException(-2, "存在未对账的明细记录") + } + + //判断本地是否有多余成功流水,并保存 + transactionReconciliationService.doCheckLocalMoreDtls(chkfile) + + return transactionReconciliationService.doConfirmChkfileStatus(chkfile) } + + } \ No newline at end of file diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt index 7e287394..b1bc339d 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/scheduler_ynrccchk_task.kt @@ -48,8 +48,8 @@ class DownloadYnrccChkfileTask { private val logger = KotlinLogging.logger { } - @Scheduled(cron = "\${download.ynrcc.chkfile.cron:-}") - @SchedulerLock(name = "DownloadYnrccChkfileSchedulerTask", lockAtMostForString = "PT10M") +// @Scheduled(cron = "\${download.ynrcc.chkfile.cron:-}") +// @SchedulerLock(name = "DownloadYnrccChkfileSchedulerTask", lockAtMostForString = "PT10M") fun doDownloadYnrccChkfile() { try { if (null == TenantContext.getTenantSchema()) TenantContext.setTenantSchema(Constants.DEFAULT_TENANTID) diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt index 6e6ade44..af771320 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/account_service_impl.kt @@ -1,6 +1,5 @@ package com.supwisdom.dlpay.api.service.impl -import com.supwisdom.dlpay.api.dao.DebitCreditDtlDao import com.supwisdom.dlpay.api.dao.TransactionMainDao import com.supwisdom.dlpay.api.domain.* import com.supwisdom.dlpay.api.repositories.AccountService @@ -10,11 +9,9 @@ import com.supwisdom.dlpay.framework.domain.TShopacc import com.supwisdom.dlpay.framework.service.SystemUtilService import com.supwisdom.dlpay.framework.util.DateUtil import com.supwisdom.dlpay.framework.util.Subject -import com.supwisdom.dlpay.framework.util.TradeDict import com.supwisdom.dlpay.framework.util.TradeDict.DTL_STATUS_SUCCESS import com.supwisdom.dlpay.framework.util.TradeDict.TRADE_FLAG_OUT import com.supwisdom.dlpay.framework.util.TradeErrorCode -import org.hibernate.Transaction import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Repository import org.springframework.stereotype.Service @@ -125,6 +122,9 @@ class ShopaccServiceImpl : ShopaccService { if (shopdtl.updateBala) { return } + if (shopdtl.status != DTL_STATUS_SUCCESS) { + return + } val amount = transactionMainDao.findByRefno(refno)?.sumAmountByAccno(shopdtl.shopaccno, Subject.SUBJNO_MACHANT_INCOME, "both") ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt index d9006870..be112d1f 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_reconciliation_service_impl.kt @@ -2,15 +2,20 @@ package com.supwisdom.dlpay.api.service.impl import com.supwisdom.dlpay.agent.citizencard.YnrccUtil import com.supwisdom.dlpay.api.bean.YnrccChkfileBean +import com.supwisdom.dlpay.api.dao.PersondtlDao import com.supwisdom.dlpay.api.dao.TransactionChkdtlDao import com.supwisdom.dlpay.api.dao.TransactionChkfileDao +import com.supwisdom.dlpay.api.dao.TransactionMainDao import com.supwisdom.dlpay.api.domain.TTransactionChkdtl import com.supwisdom.dlpay.api.domain.TTransactionChkfile import com.supwisdom.dlpay.api.service.TransactionReconciliationService +import com.supwisdom.dlpay.api.service.TransactionServiceProxy import com.supwisdom.dlpay.exception.TransactionCheckException import com.supwisdom.dlpay.framework.dao.BusinessparaDao import com.supwisdom.dlpay.framework.service.SystemUtilService import com.supwisdom.dlpay.framework.tenant.TenantContext +import com.supwisdom.dlpay.framework.util.MoneyUtil +import com.supwisdom.dlpay.framework.util.TradeDict import com.supwisdom.dlpay.framework.util.TradeErrorCode import com.supwisdom.dlpay.util.ConstantUtil import org.springframework.beans.factory.annotation.Autowired @@ -26,6 +31,12 @@ class TransactionReconciliationServiceImpl : TransactionReconciliationService { private lateinit var systemUtilService: SystemUtilService @Autowired private lateinit var businessparaDao: BusinessparaDao + @Autowired + private lateinit var transactionMainDao: TransactionMainDao + @Autowired + private lateinit var persondtlDao: PersondtlDao + @Autowired + private lateinit var transactionService: TransactionServiceProxy override fun getTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile? { return transactionChkfileDao.getByAccdateAndSourcetype(accdate, sourcetype) @@ -38,25 +49,13 @@ class TransactionReconciliationServiceImpl : TransactionReconciliationService { throw TransactionCheckException(TradeErrorCode.BUSINESS_DEAL_ERROR, "accdate=$accdate,sourcetype=$sourcetype 的chkfile已经存在") it } else { - transactionChkfileDao.save(TTransactionChkfile().apply { - this.accdate = accdate - this.sourcetype = sourcetype - this.status = ConstantUtil.CHKFILE_STATUS_INIT - this.result = ConstantUtil.CHKFILE_RESULT_NONE - this.remark = null - this.othercnt = 0 - this.otheramt = 0.00 - this.localcnt = 0 - this.localamt = 0.00 - this.lastsaved = systemUtilService.sysdatetime.sysdate - this.tenantid = TenantContext.getTenantSchema() - }) //保存init对账文件 + saveInitTransactionChkfile(accdate, sourcetype) //保存init对账文件 } } } - override fun saveOrUpdateTransactionChkfile(chkfile: TTransactionChkfile) { - transactionChkfileDao.save(chkfile) + override fun saveOrUpdateTransactionChkfile(chkfile: TTransactionChkfile): TTransactionChkfile { + return transactionChkfileDao.save(chkfile) } override fun saveYnrccTransactionChkDtl(chkfile: TTransactionChkfile, bean: YnrccChkfileBean): TTransactionChkdtl { @@ -97,4 +96,134 @@ class TransactionReconciliationServiceImpl : TransactionReconciliationService { businessparaDao.updateBusinessparaValue(YnrccUtil.YNRCC_BILLS_DOWNLOAD_LASTDATE, chkfile.accdate) //更新下载对账单日期 } + override fun deleteTransactionChkdtls(chkfileId: String) { + transactionChkdtlDao.deleteByChkfileid(chkfileId) + } + + override fun saveInitTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile { + return transactionChkfileDao.save(TTransactionChkfile().apply { + this.accdate = accdate + this.sourcetype = sourcetype + this.status = ConstantUtil.CHKFILE_STATUS_INIT + this.result = ConstantUtil.CHKFILE_RESULT_NONE + this.remark = null + this.othercnt = 0 + this.otheramt = 0.00 + this.localcnt = 0 + this.localamt = 0.00 + this.lastsaved = systemUtilService.sysdatetime.sysdate + this.tenantid = TenantContext.getTenantSchema() + }) + } + + override fun doCheckEqualTransdtls(chkfile: TTransactionChkfile) { + //所有一致的记录,一次任务处理 + transactionChkdtlDao.getCheckEqualDetails(chkfile.id)?.forEach { chkdtl -> + chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_EQUAL + chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_EQUAL + chkdtl.remark = "双方交易一致" + transactionChkdtlDao.save(chkdtl) //对账明细表更新 + + transactionService.checkSuccessConfirm(chkdtl.localRefno, chkdtl.otherAccdate) + } + } + + override fun getUncheckTransactionChkdtls(chkfileId: String): List { + return transactionChkdtlDao.getUncheckTransactionChkdtls(chkfileId) ?: ArrayList(0) + } + + override fun doCheckTransactionChkdtl(chkdtl: TTransactionChkdtl) { + val transMain = transactionMainDao.findByRefno(chkdtl.localRefno) + + if (null == transMain || !transMain.person) { + chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_NOTEXIST + chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP + chkdtl.remark = "本地流水不存在" + transactionChkdtlDao.save(chkdtl) //对账明细表更新 + } + + if(!MoneyUtil.moneyEqual(chkdtl.amount,transMain.personDtl.amount)){ + chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_DIFF + chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP + chkdtl.remark = "交易金额不相等" + transactionChkdtlDao.save(chkdtl) //对账明细表更新 + } + + if(transMain.accdate!=chkdtl.accdate || transMain.sourceType != chkdtl.sourcetype){ + //TODO: 数据异常?? + chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_ERROR + chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP + chkdtl.remark = "记账日期或支付方式错误" + transactionChkdtlDao.save(chkdtl) //对账明细表更新 + } + + if (transMain.status == TradeDict.DTL_STATUS_SUCCESS) { + chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_EQUAL + chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_EQUAL + chkdtl.remark = "双方交易一致" + transactionChkdtlDao.save(chkdtl) //对账明细表更新 + + transactionService.checkSuccessConfirm(chkdtl.localRefno, chkdtl.otherAccdate) + } else { + //补账 + transactionService.repair(transMain.refno, chkdtl.otherAccdate, chkdtl.otherRefno, "补账成功") + + chkdtl.chkresult = ConstantUtil.CHKDTL_CHKRESULT_NOCHARGE + chkdtl.resolved = ConstantUtil.CHKDTL_RESOLVED_EQUAL + chkdtl.remark = "本地未入账,补账成功" + transactionChkdtlDao.save(chkdtl) //对账明细表更新 + } + } + + override fun checkUncheckExists(chkfileId: String): Boolean { + return transactionChkdtlDao.getUncheckCount(chkfileId).existed > 0 + } + + override fun doCheckLocalMoreDtls(chkfile: TTransactionChkfile) { + transactionChkdtlDao.findLocalMoreDtls(chkfile.accdate, chkfile.sourcetype, chkfile.id)?.forEach { refno -> + //保存多余的记录 + transactionMainDao.findByRefno(refno)?.let { transMain -> + if (TradeDict.DTL_STATUS_SUCCESS == transMain.status && transMain.accdate == chkfile.accdate && transMain.sourceType == chkfile.sourcetype) { + transactionChkdtlDao.save(TTransactionChkdtl().apply { + this.chkfileId = chkfile.id + this.accdate = chkfile.accdate + this.sourcetype = chkfile.sourcetype + this.recordno = null + this.amount = transMain.personDtl.amount + this.otherRefno = transMain.reverseRefno ?: "0" + this.localRefno = transMain.refno + this.otherAccdate = transMain.accdate + this.transtype = when (transMain.reverseType) { + "none" -> "pay" + else -> transMain.reverseType + } + this.otherStatus = "unknown" + this.remark = "本地成功流水第三方流水不存在" + this.extdata = transMain.personDtl.transdesc + this.chkresult = ConstantUtil.CHKDTL_CHKRESULT_NOTEXIST + this.resolved = ConstantUtil.CHKDTL_RESOLVED_HANGUP + this.lastsaved = systemUtilService.sysdatetime.sysdate + this.tenantid = chkfile.tenantid + }) //保存本地多出的记录 + } + } + } + } + + override fun doConfirmChkfileStatus(chkfile: TTransactionChkfile): TTransactionChkfile { + val personSumInfo = persondtlDao.getPersondtlSumInfo(chkfile.accdate, chkfile.sourcetype, chkfile.tenantid) + chkfile.localcnt = personSumInfo.totalcnt ?: 0 + chkfile.localamt = personSumInfo.totalamt ?: 0.00 + chkfile.status = ConstantUtil.CHKFILE_STATUS_finish //对账结束 + if (chkfile.othercnt == chkfile.localcnt && MoneyUtil.moneyEqual(chkfile.otheramt, chkfile.localamt)) { + //fixme: 是否还需判断chkdtl中resolved是否都equal + chkfile.result = ConstantUtil.CHKFILE_RESULT_EQUAL + chkfile.remark = "对账完成,双方一致" + } else { + chkfile.result = ConstantUtil.CHKFILE_RESULT_UNEQUAL + chkfile.remark = "对账不平,请查看明细数据" + } + transactionChkfileDao.save(chkfile) + return chkfile + } } \ No newline at end of file diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt index eb74c4c7..b708983f 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/impl/transaction_service_impl.kt @@ -379,11 +379,11 @@ class TransactionServiceImpl : TransactionService { ?: throw TransactionProcessException(TradeErrorCode.BUSINESS_DEAL_ERROR, "系统异常,无法处理退款流水") originTrans.reverseFlag = transaction.reverseType - if(originTrans.person){ + if (originTrans.person) { originTrans.personDtl.reverseFlag = originTrans.reverseFlag originTrans.personDtl.reverseAmount = originTrans.refundAmount } - if(originTrans.shop){ + if (originTrans.shop) { originTrans.shopDtl.reverseFlag = originTrans.reverseFlag } transactionMainDao.save(originTrans) @@ -391,8 +391,8 @@ class TransactionServiceImpl : TransactionService { transaction.endTime = systemUtilService.sysdatetime.sysdate transactionMainDao.save(transaction) - if(transaction.person&&!transaction.personDtl.userid.isNullOrEmpty()){ - kafkaSendMsgService.sendJpushMessage(transaction.personDtl.userid,"交易提醒","你有一笔${transaction.personDtl.amount}元的支出,点击查看详情",transaction.refno, mutableMapOf(),transaction.tenantid) + if (transaction.person && !transaction.personDtl.userid.isNullOrEmpty()) { + kafkaSendMsgService.sendJpushMessage(transaction.personDtl.userid, "交易提醒", "你有一笔${transaction.personDtl.amount}元的支出,点击查看详情", transaction.refno, mutableMapOf(), transaction.tenantid) } return transaction } @@ -504,7 +504,7 @@ class TransactionServiceImpl : TransactionService { -it.amount, "${it.summary}$summarySuffix") } builder.dtltype = originTrans.dtltype - if(builder.operId.isNullOrEmpty()){ + if (builder.operId.isNullOrEmpty()) { builder.operator(originTrans.operid, originTrans.opertype) } return builderRecords(builder, TradeDict.DTL_STATUS_INIT) @@ -533,7 +533,19 @@ class TransactionServiceImpl : TransactionService { } } - override fun repair(refno: String, remark: String): TTransactionMain { + override fun checkSuccessConfirm(refno: String, agentAccdate: String): TTransactionMain { + val transMain = transactionMainDao.findByRefnoForUpdate(refno) + ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, + "本地流水<$refno>不存在") + transMain.settleDate = agentAccdate + transMain.details?.forEach { + it.settleDate = agentAccdate + } + transactionMainDao.save(transMain) + return transMain + } + + override fun repair(refno: String, agentAccdate: String, sourcetypeRefno: String, remark: String): TTransactionMain { val transaction = transactionMainDao.findByRefnoForUpdate(refno) ?: throw TransactionProcessException(TradeErrorCode.TRANSACTION_NOT_EXISTS, "补帐交易流水<$refno>不存在") @@ -545,8 +557,22 @@ class TransactionServiceImpl : TransactionService { "补帐交易<$refno>状态错误,status<${transaction.status}>") } - transactionOnSuccess(transaction, remark, true) - transaction.checkDate = systemUtilService.accdate + transaction.status = TradeDict.DTL_STATUS_SUCCESS //置为成功 + transactionOnSuccess(transaction, sourcetypeRefno, true) +// transaction.checkDate = systemUtilService.accdate + transaction.settleDate = agentAccdate + transaction.details?.forEach { + it.settleDate = agentAccdate + } + if(transaction.person){ + transaction.personDtl.remark = remark + } + if(transaction.shop){ + transaction.personDtl.remark = remark + } + if(transaction.subject){ + // + } transaction.endTime = systemUtilService.sysdatetime.sysdate transactionMainDao.save(transaction) diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt index 8147a59c..c2935c5b 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_reconciliation_service.kt @@ -13,7 +13,7 @@ interface TransactionReconciliationService { fun doInitTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile @Transactional(rollbackFor = [Exception::class]) - fun saveOrUpdateTransactionChkfile(chkfile: TTransactionChkfile) + fun saveOrUpdateTransactionChkfile(chkfile: TTransactionChkfile): TTransactionChkfile @Transactional(rollbackFor = [Exception::class]) fun saveYnrccTransactionChkDtl(chkfile: TTransactionChkfile, bean: YnrccChkfileBean): TTransactionChkdtl @@ -22,6 +22,30 @@ interface TransactionReconciliationService { fun doBatchSaveYnrccTransactionChkDtl(chkfile: TTransactionChkfile, list: ArrayList): Boolean @Transactional(rollbackFor = [Exception::class]) - fun doSuccessTransactionChkfile(chkfile: TTransactionChkfile, remark:String) + fun doSuccessTransactionChkfile(chkfile: TTransactionChkfile, remark: String) + + @Transactional(rollbackFor = [Exception::class]) + fun deleteTransactionChkdtls(chkfileId: String) + + @Transactional(rollbackFor = [Exception::class]) + fun saveInitTransactionChkfile(accdate: String, sourcetype: String): TTransactionChkfile + + @Transactional(rollbackFor = [Exception::class]) + fun doCheckEqualTransdtls(chkfile: TTransactionChkfile) + + @Transactional(rollbackFor = [Exception::class], readOnly = true) + fun getUncheckTransactionChkdtls(chkfileId: String): List + + @Transactional(rollbackFor = [Exception::class]) + fun doCheckTransactionChkdtl(chkdtl: TTransactionChkdtl) + + @Transactional(rollbackFor = [Exception::class], readOnly = true) + fun checkUncheckExists(chkfileId: String):Boolean + + @Transactional(rollbackFor = [Exception::class]) + fun doCheckLocalMoreDtls(chkfile: TTransactionChkfile) + + @Transactional(rollbackFor = [Exception::class]) + fun doConfirmChkfileStatus(chkfile: TTransactionChkfile): TTransactionChkfile } \ No newline at end of file diff --git a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt index eb08287b..4ab8b655 100644 --- a/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt +++ b/payapi/src/main/kotlin/com/supwisdom/dlpay/api/service/transaction_service.kt @@ -44,9 +44,15 @@ interface TransactionService { @Transactional fun cancelInit(originRefno: String, builder: TransactionBuilder): TTransactionMain + /** + * 对账一致处理接口 + * */ + @Transactional(rollbackFor = [Exception::class]) + fun checkSuccessConfirm(refno: String, agentAccdate: String): TTransactionMain + // 补帐接口 - @Transactional - fun repair(refno: String, remark: String): TTransactionMain + @Transactional(rollbackFor = [Exception::class]) + fun repair(refno: String, agentAccdate: String, sourcetypeRefno: String, remark:String): TTransactionMain } @Service @@ -111,4 +117,17 @@ class TransactionServiceProxy { } return trans } + + fun checkSuccessConfirm(refno: String, agentAccdate: String): TTransactionMain { + return transactionService.checkSuccessConfirm(refno, agentAccdate) + } + + fun repair(refno: String, agentAccdate: String, sourcetypeRefno: String, remark: String): TTransactionMain { + return transactionService.repair(refno, agentAccdate, sourcetypeRefno, remark).also { + if (it.shop) { + shopAccBalanceAsyncTask.updateShopBalance(it.shopDtl) + } + } + } + } \ No newline at end of file -- 2.17.1