Added remitterAddress, beneficiaryName, beneficiaryAddress, senderAcctType, beneficiaryAcctType, beneficiaryBankName, beneficiaryBranchName, commissionAmount to transactions as told by C-Edge. Also removed errorMsg from TransactionFailureResponse class. Refactored code for more readability. Removed application logs from STDOUT.

This commit is contained in:
Md Asif 2024-10-24 12:39:07 +05:30
parent df7d0e8006
commit 6c5dab0a17
12 changed files with 100 additions and 51 deletions

3
.gitignore vendored
View File

@ -33,4 +33,5 @@ out/
/.nb-gradle/ /.nb-gradle/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
logs/application.log

View File

@ -1,16 +1,15 @@
package net.ipksindia package net.ipksindia
import net.ipksindia.model.TransactionRequest
import net.ipksindia.config.AppConfig import net.ipksindia.config.AppConfig
import net.ipksindia.dao.TellerDao import net.ipksindia.dao.TellerDao
import net.ipksindia.dao.TransactionDao import net.ipksindia.dao.TransactionDao
import net.ipksindia.model.NeftTransaction import net.ipksindia.model.NeftTransaction
import net.ipksindia.model.OutwardNeftResponse import net.ipksindia.model.OutwardNeftResponse
import net.ipksindia.model.TransactionRequest
import net.ipksindia.model.TransferTransaction import net.ipksindia.model.TransferTransaction
import net.ipksindia.response.TransactionFailureResponse
import org.slf4j.Logger import org.slf4j.Logger
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import response.TransactionFailureResponse
import response.TransactionResponse
import response.TransactionSuccessResponse import response.TransactionSuccessResponse
class NeftRequestProcessor { class NeftRequestProcessor {
@ -78,9 +77,9 @@ class NeftRequestProcessor {
): OutwardNeftResponse { ): OutwardNeftResponse {
val (transferResponse, neftResponse) = TransactionExecutor().executePair(transactionPair) val (transferResponse, neftResponse) = TransactionExecutor().executePair(transactionPair)
return if (isSuccess(transferResponse, neftResponse)) { return if (transferResponse is TransactionSuccessResponse && neftResponse is TransactionSuccessResponse) {
val transferQueueNumber = (transferResponse as TransactionSuccessResponse).queueNumber val transferQueueNumber = transferResponse.queueNumber
val neftQueueNumber = (neftResponse as TransactionSuccessResponse).queueNumber val neftQueueNumber = neftResponse.queueNumber
TransactionDao().updateSuccessTransaction(transactionRequest, transferQueueNumber, neftQueueNumber) TransactionDao().updateSuccessTransaction(transactionRequest, transferQueueNumber, neftQueueNumber)
logger.info("TXN: #{} UPDATED RESULTS SUCCESSFULLY", transactionNumber) logger.info("TXN: #{} UPDATED RESULTS SUCCESSFULLY", transactionNumber)
@ -91,11 +90,6 @@ class NeftRequestProcessor {
} }
} }
/**
* Check if both transfer and NEFT responses are successful.
*/
private fun isSuccess(transferResponse: TransactionResponse, neftResponse: TransactionResponse) = transferResponse is TransactionSuccessResponse && neftResponse is TransactionSuccessResponse
/** /**
* Log errors if the transaction fails. * Log errors if the transaction fails.
*/ */
@ -104,8 +98,8 @@ class NeftRequestProcessor {
transferResponse: Any, transferResponse: Any,
neftResponse: Any neftResponse: Any
) { ) {
val transferErrorMsg = (transferResponse as? TransactionFailureResponse)?.errorMsg ?: "Unknown Error" val transferErrorMsg = (transferResponse as? TransactionFailureResponse)?.message ?: "Unknown Error"
val neftErrorMsg = (neftResponse as? TransactionFailureResponse)?.errorMsg ?: "Unknown Error" val neftErrorMsg = (neftResponse as? TransactionFailureResponse)?.message ?: "Unknown Error"
logger.error("TXN: #{} TRANSFER TXN FAILED DUE TO: {}", transactionNumber, transferErrorMsg) logger.error("TXN: #{} TRANSFER TXN FAILED DUE TO: {}", transactionNumber, transferErrorMsg)
logger.error("TXN: #{} NEFT TXN FAILED DUE TO: {}", transactionNumber, neftErrorMsg) logger.error("TXN: #{} NEFT TXN FAILED DUE TO: {}", transactionNumber, neftErrorMsg)

View File

@ -4,19 +4,19 @@ import kotlinx.serialization.json.Json
import net.ipksindia.config.AppConfig import net.ipksindia.config.AppConfig
import net.ipksindia.model.NeftTransaction import net.ipksindia.model.NeftTransaction
import net.ipksindia.model.TransferTransaction import net.ipksindia.model.TransferTransaction
import net.ipksindia.response.TransactionFailureResponse
import okhttp3.MediaType.Companion.toMediaType import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject import org.json.JSONObject
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import response.TransactionFailureResponse
import response.TransactionResponse import response.TransactionResponse
import response.TransactionSuccessResponse import response.TransactionSuccessResponse
import java.io.IOException import java.io.IOException
class TransactionExecutor() { class TransactionExecutor {
private val logger = LoggerFactory.getLogger(TransactionExecutor::class.java) private val logger = LoggerFactory.getLogger(TransactionExecutor::class.java)
private val transactionUrl = AppConfig.remoteServerConfig.transactionUrl private val transactionUrl = AppConfig.remoteServerConfig.transactionUrl
@ -24,17 +24,18 @@ class TransactionExecutor() {
val transferTransaction = transactionPair.first val transferTransaction = transactionPair.first
val neftTransaction = transactionPair.second val neftTransaction = transactionPair.second
logger.debug("TRF-RRN: {}, NEFT-RRN: {}", transferTransaction.rrn, neftTransaction.rrn)
val transferResponseString = execute(Json.encodeToString(transferTransaction)) val transferResponseString = execute(Json.encodeToString(transferTransaction))
logger.debug("TRANSFER-RRN: {} - CBS Response: {}", transferTransaction.rrn, transferResponseString)
val transferResponse = processResponse(transferResponseString) val transferResponse = processResponse(transferResponseString)
val neftResponseString = execute(Json.encodeToString(neftTransaction)) val neftResponseString = execute(Json.encodeToString(neftTransaction))
logger.debug("NEFT-RRN: {}, CBS Response: {}", neftTransaction.rrn, neftResponseString)
val neftResponse = processResponse(neftResponseString) val neftResponse = processResponse(neftResponseString)
return Pair(transferResponse, neftResponse) return Pair(transferResponse, neftResponse)
} }
private fun execute(postBody: String): String { private fun execute(postBody: String): String {
logger.debug("request: {}", postBody)
val jsonMediaType = "application/json; charset=utf-8".toMediaType() val jsonMediaType = "application/json; charset=utf-8".toMediaType()
val httpClient = OkHttpClient val httpClient = OkHttpClient
@ -52,7 +53,9 @@ class TransactionExecutor() {
if (!response.isSuccessful) { if (!response.isSuccessful) {
throw IOException("Unexpected response: ${response.body}") throw IOException("Unexpected response: ${response.body}")
} }
response.body?.string() ?: throw IOException("no response body") val responseString = response.body?.string() ?: throw IOException("no response body")
logger.debug("response: {}", responseString)
responseString
} }
} }
@ -63,14 +66,11 @@ class TransactionExecutor() {
val message = responseObj.getString("message") val message = responseObj.getString("message")
val error = responseObj.getInt("error") val error = responseObj.getInt("error")
if(responseBody.contains("SUCCESS")) { return if (responseBody.contains("SUCCESS")) {
val queueNo = responseObj.getJSONObject("response").getString("QueueId") val queueNo = responseObj.getJSONObject("response").getString("QueueId")
return TransactionSuccessResponse(status, message, queueNo, error) TransactionSuccessResponse(status, message, queueNo, error)
} else { } else {
val errorMsg = responseObj.getJSONObject("response").getString("errorMsg") TransactionFailureResponse(status, message, error)
return TransactionFailureResponse(status, message, errorMsg, error)
} }
} }
}
}

View File

@ -1,8 +1,8 @@
package net.ipksindia package net.ipksindia
import enums.TransactionType import enums.TransactionType
import net.ipksindia.model.NeftTransaction
import model.Teller import model.Teller
import net.ipksindia.model.NeftTransaction
import net.ipksindia.model.TransactionRequest import net.ipksindia.model.TransactionRequest
import net.ipksindia.model.TransferTransaction import net.ipksindia.model.TransferTransaction
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -13,10 +13,13 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
private val rrn = transactionRequest.date.format(DateTimeFormatter.ofPattern("ddMM")) + transactionRequest.transactionNumber.takeLast(4) private val rrn = transactionRequest.date.format(DateTimeFormatter.ofPattern("ddMM")) + transactionRequest.transactionNumber.takeLast(4)
private fun createTransferTransaction(): TransferTransaction { private fun createTransferTransaction(): TransferTransaction {
val bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')] ?: throw ItemNotFoundException("SFTP code for", transactionRequest.dccbCode) val bankCode = bankDccbToSftpMap[transactionRequest.dccbCode.padStart(4, '0')] ?: throw ItemNotFoundException(
"SFTP code",
transactionRequest.dccbCode
)
return TransferTransaction( return TransferTransaction(
bankCode = bankCode, bankCode = bankCode,
branchCode = transactionRequest.branchCode.padStart(3,'0'), branchCode = transactionRequest.branchCode.padStart(3, '0'),
cbsTellerId = teller.tellerId, cbsTellerId = teller.tellerId,
cbsTellerUserType = teller.userType, cbsTellerUserType = teller.userType,
queIdType = "5", queIdType = "5",
@ -36,7 +39,15 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
remitterName = transactionRequest.remitterName, remitterName = transactionRequest.remitterName,
ifscCode = "ABCD0000000", ifscCode = "ABCD0000000",
rrn = rrn + "1", rrn = rrn + "1",
mobileOrEmail = transactionRequest.mobileNumber mobileOrEmail = transactionRequest.mobileNumber,
remitterAddress = "",
beneficiaryName = "",
beneficiaryAddress = "",
senderAcctType = "",
beneficiaryAcctType = "",
beneficiaryBankName = "",
beneficiaryBranchName = "",
commissionAmt = "0"
) )
} }
@ -64,8 +75,16 @@ class TransactionFactory(private val transactionRequest: TransactionRequest, pri
apiType = "OUTWARD_QUEUE_POSTING", apiType = "OUTWARD_QUEUE_POSTING",
remitterName = transactionRequest.remitterName, remitterName = transactionRequest.remitterName,
ifscCode = transactionRequest.ifscCode, ifscCode = transactionRequest.ifscCode,
rrn = rrn + "2",
mobileOrEmail = transactionRequest.mobileNumber, mobileOrEmail = transactionRequest.mobileNumber,
rrn = rrn + "2" remitterAddress = transactionRequest.remitterAddress.take(25),
beneficiaryName = transactionRequest.beneficiaryName,
beneficiaryAddress = transactionRequest.beneficiaryAddress.take(25),
senderAcctType = transactionRequest.senderAcctType,
beneficiaryAcctType = transactionRequest.beneficiaryAcctType,
beneficiaryBankName = transactionRequest.beneficiaryBankName,
beneficiaryBranchName = transactionRequest.beneficiaryBranchName,
commissionAmt = "0"
) )
} }

View File

@ -1,7 +1,7 @@
package net.ipksindia.dao package net.ipksindia.dao
import net.ipksindia.model.TransactionRequest
import net.ipksindia.ItemNotFoundException import net.ipksindia.ItemNotFoundException
import net.ipksindia.model.TransactionRequest
import java.sql.Date import java.sql.Date
import java.sql.ResultSet import java.sql.ResultSet
import java.sql.SQLException import java.sql.SQLException
@ -9,7 +9,7 @@ import java.sql.SQLException
class TransactionDao { class TransactionDao {
private val singleTransactionRequestQuery = """ private val singleTransactionRequestQuery = """
SELECT SELECT
txn_no, txn_no,
TRIM(src_ac_no) AS src_ac_no, TRIM(src_ac_no) AS src_ac_no,
TRIM(dest_ac_no) AS dest_ac_no, TRIM(dest_ac_no) AS dest_ac_no,
@ -32,12 +32,16 @@ class TransactionDao {
ipks_accno AS pacs_acc_no, ipks_accno AS pacs_acc_no,
da.link_accno AS cbs_sb_acc_no, da.link_accno AS cbs_sb_acc_no,
'pacs_db' AS db_name, 'pacs_db' AS db_name,
kh.mobile_no kh.mobile_no,
FROM neft_rtgs_txn t kh.address_1 || kh.address_2 AS remitter_address,
JOIN dep_account da ON t.ipks_accno = da.key_1 if.idi_bank_name AS beneficiary_bank_name,
JOIN kyc_hdr kh ON da.customer_no = kh.cif_no if.idi_branch_name AS beneficiary_branch_name
WHERE FROM neft_rtgs_txn t
t.txn_no = ? JOIN dep_account da ON t.ipks_accno = da.key_1
JOIN kyc_hdr kh ON da.customer_no = kh.cif_no
JOIN idi_ifsc_dir_info if ON if.idi_ifsc_code = t.ifsc_code
WHERE
t.txn_no = ?
""".trimIndent() """.trimIndent()
private val transactionUpdateQuery = """ private val transactionUpdateQuery = """
@ -122,8 +126,8 @@ private fun mapToObject(rs: ResultSet): TransactionRequest? {
date = rs.getDate("txn_date").toLocalDate(), date = rs.getDate("txn_date").toLocalDate(),
tellerId = rs.getString("teller_id"), tellerId = rs.getString("teller_id"),
status = rs.getString("status"), status = rs.getString("status"),
beneficiaryName = rs.getString("beneficiary_name"), beneficiaryName = rs.getString("beneficiary_name") ?: "UNKNOWN",
beneficiaryAddress = rs.getString("beneficiary_add"), beneficiaryAddress = rs.getString("beneficiary_add") ?: "UNKNOWN",
pacsId = rs.getString("pacs_id"), pacsId = rs.getString("pacs_id"),
commissionTransactionNumber = rs.getString("comm_txn_no"), commissionTransactionNumber = rs.getString("comm_txn_no"),
commissionAmount = rs.getString("comm_txn_amt"), commissionAmount = rs.getString("comm_txn_amt"),
@ -132,7 +136,12 @@ private fun mapToObject(rs: ResultSet): TransactionRequest? {
remitterName = rs.getString("remitter_name"), remitterName = rs.getString("remitter_name"),
pacsAccountNumber = rs.getString("pacs_acc_no"), pacsAccountNumber = rs.getString("pacs_acc_no"),
linkedCBSAccountNumber = rs.getString("cbs_sb_acc_no"), linkedCBSAccountNumber = rs.getString("cbs_sb_acc_no"),
mobileNumber = rs.getString("mobile_no") ?: "999999999" mobileNumber = rs.getString("mobile_no") ?: "999999999",
remitterAddress = rs.getString("remitter_address"),
beneficiaryBankName = rs.getString("beneficiary_bank_name"),
beneficiaryBranchName = rs.getString("beneficiary_branch_name"),
senderAcctType = "10", //for savings as shared by c-edge
beneficiaryAcctType = "10" //for savings as shared by c-edge
) )
} }
return null return null

View File

@ -1,7 +1,6 @@
package net.ipksindia.model package net.ipksindia.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import org.ipks.model.Transaction
@Serializable @Serializable
class NeftTransaction( class NeftTransaction(
@ -27,4 +26,12 @@ class NeftTransaction(
override val ifscCode: String, override val ifscCode: String,
override val mobileOrEmail: String, override val mobileOrEmail: String,
override val rrn: String, override val rrn: String,
override val remitterAddress: String,
override val beneficiaryName: String,
override val beneficiaryAddress: String,
override val senderAcctType: String,
override val beneficiaryAcctType: String,
override val beneficiaryBankName: String,
override val beneficiaryBranchName: String,
override val commissionAmt: String,
) : Transaction ) : Transaction

View File

@ -1,4 +1,4 @@
package org.ipks.model package net.ipksindia.model
interface Transaction { interface Transaction {
val bankCode: String val bankCode: String
@ -22,5 +22,13 @@ interface Transaction {
val remitterName: String val remitterName: String
val ifscCode: String val ifscCode: String
val mobileOrEmail: String val mobileOrEmail: String
val remitterAddress: String
val beneficiaryName: String
val beneficiaryAddress: String
val senderAcctType: String
val beneficiaryAcctType: String
val beneficiaryBankName: String
val beneficiaryBranchName: String
val commissionAmt: String
val rrn: String val rrn: String
} }

View File

@ -13,7 +13,7 @@ data class TransactionRequest(
val tellerId: String, val tellerId: String,
val status: String, val status: String,
val beneficiaryName: String, val beneficiaryName: String,
val beneficiaryAddress: String?, val beneficiaryAddress: String,
val pacsId: String, val pacsId: String,
val commissionTransactionNumber: String?, val commissionTransactionNumber: String?,
val commissionAmount: String?, val commissionAmount: String?,
@ -22,6 +22,11 @@ data class TransactionRequest(
val remitterName: String, val remitterName: String,
val pacsAccountNumber: String, val pacsAccountNumber: String,
val linkedCBSAccountNumber: String, val linkedCBSAccountNumber: String,
val mobileNumber: String val mobileNumber: String,
val remitterAddress: String,
val beneficiaryBankName: String,
val beneficiaryBranchName: String,
val senderAcctType: String,
val beneficiaryAcctType: String
) )

View File

@ -1,7 +1,6 @@
package net.ipksindia.model package net.ipksindia.model
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import org.ipks.model.Transaction
@Serializable @Serializable
class TransferTransaction( class TransferTransaction(
@ -27,4 +26,12 @@ class TransferTransaction(
override val ifscCode: String, override val ifscCode: String,
override val mobileOrEmail: String, override val mobileOrEmail: String,
override val rrn: String, override val rrn: String,
override val remitterAddress: String,
override val beneficiaryName: String,
override val beneficiaryAddress: String,
override val senderAcctType: String,
override val beneficiaryAcctType: String,
override val beneficiaryBankName: String,
override val beneficiaryBranchName: String,
override val commissionAmt: String,
) : Transaction ) : Transaction

View File

@ -1,12 +1,12 @@
package response package net.ipksindia.response
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import response.TransactionResponse
@Serializable @Serializable
data class TransactionFailureResponse( data class TransactionFailureResponse(
override val status: String, override val status: String,
override val message: String, override val message: String,
val errorMsg: String,
override val error: Int override val error: Int
): TransactionResponse ): TransactionResponse

View File

@ -10,7 +10,7 @@ bank {
server { server {
protocol = "http" protocol = "http"
host = "localhost" host = "localhost"
port = 3000 port = 8080
rootRoute = "IPKS_Queue_Generation" rootRoute = "IPKS_Queue_Generation"
transactionRoute = "IpksApi" transactionRoute = "IpksApi"
} }

View File

@ -26,7 +26,6 @@
<logger name="io.netty" level="WARN"/> <logger name="io.netty" level="WARN"/>
<logger name="net.ipksindia" level="DEBUG" additivity="false"> <logger name="net.ipksindia" level="DEBUG" additivity="false">
<appender-ref ref="FILE-ROLLING"/> <appender-ref ref="FILE-ROLLING"/>
<appender-ref ref="STDOUT" />
</logger> </logger>
<root level="INFO"> <root level="INFO">