diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..aa13dbe
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ oracle.19
+ true
+ false
+ oracle.jdbc.OracleDriver
+ jdbc:oracle:thin:@ipksprod3.c7q7defafeea.ap-south-1.rds.amazonaws.com:1521:IPKS
+
+
+
+
+
+
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..d4b7acc
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt
index ff5fe3e..f7427e8 100644
--- a/src/main/kotlin/Main.kt
+++ b/src/main/kotlin/Main.kt
@@ -17,6 +17,7 @@ fun main() {
val neftTransaction = transactionFactory.createNEFTTransaction()
val transactionPair = Pair(transferTransaction, neftTransaction)
val success = TransactionExecutor().execute(transactionPair)
+ print(success)
}
}
diff --git a/src/main/kotlin/ResponseData.kt b/src/main/kotlin/ResponseData.kt
new file mode 100644
index 0000000..4485f46
--- /dev/null
+++ b/src/main/kotlin/ResponseData.kt
@@ -0,0 +1,14 @@
+import kotlinx.serialization.Serializable
+
+
+@Serializable
+data class ResponseData (
+ val transactionDate: Int,
+ val sourceStat: String,
+ val journalId: String,
+ val queueId: String,
+ val error: String,
+ val apiType: String,
+ val errorMsg: String,
+ val txnScreenNo: String
+)
\ No newline at end of file
diff --git a/src/main/kotlin/TellerNotFoundException.kt b/src/main/kotlin/TellerNotFoundException.kt
new file mode 100644
index 0000000..bbad8c0
--- /dev/null
+++ b/src/main/kotlin/TellerNotFoundException.kt
@@ -0,0 +1 @@
+class TellerNotFoundException(s: String) : Exception(s)
\ No newline at end of file
diff --git a/src/main/kotlin/TransactionExecutor.kt b/src/main/kotlin/TransactionExecutor.kt
new file mode 100644
index 0000000..b9ce58a
--- /dev/null
+++ b/src/main/kotlin/TransactionExecutor.kt
@@ -0,0 +1,55 @@
+
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.Json
+import model.NeftTransaction
+import okhttp3.MediaType.Companion.toMediaType
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.RequestBody.Companion.toRequestBody
+import model.TransferTransaction
+
+
+class TransactionExecutor() {
+
+ private val protocol = "http"
+ private val host = "localhost"
+ private val port = "3000"
+ private val rootRoute = "WESTBANGAL/api"
+ private val remoteUrl = "$protocol://$host:$port/$rootRoute"
+
+ fun execute(transactionPair: Pair): Boolean {
+
+ val transferTransaction = transactionPair.first
+ val neftTransaction = transactionPair.second
+ val transferSuccess = execute(Json.encodeToString(transferTransaction))
+ if(!transferSuccess) {
+ return false
+ }
+ val neftSuccess = execute(Json.encodeToString(neftTransaction))
+ return neftSuccess
+ }
+
+ fun execute(postBody: String): Boolean {
+ val transferRoute = "IPKSNeftRtgsApiTransfer"
+ val transferURL = "$remoteUrl/$transferRoute"
+ val jsonMediaType = "application/json; charset=utf-8".toMediaType()
+
+ val httpClient = OkHttpClient()
+
+ val request = Request.Builder()
+ .url(transferURL)
+ .post(postBody.toRequestBody(jsonMediaType))
+ .build()
+
+ httpClient.newCall(request).execute().use { response ->
+ if (!response.isSuccessful) {
+ return false
+ }
+ response.body!!.string()
+ }
+
+ println("success")
+ return true
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/kotlin/TransactionFactory.kt b/src/main/kotlin/TransactionFactory.kt
new file mode 100644
index 0000000..d7d8270
--- /dev/null
+++ b/src/main/kotlin/TransactionFactory.kt
@@ -0,0 +1,63 @@
+
+import model.NeftTransaction
+import model.Teller
+import model.TransactionRequest
+import model.TransferTransaction
+import enums.TransactionType
+import java.time.format.DateTimeFormatter
+
+class TransactionFactory(private val transactionRequest: TransactionRequest, private val teller: Teller) {
+
+ private val date = transactionRequest.date.format(DateTimeFormatter.ofPattern("dd-MM-yyyy"))
+ private val rrn = transactionRequest.date.format(DateTimeFormatter.ofPattern("ddMM")) + transactionRequest.transactionNumber.takeLast(4)
+
+ fun createTransferTransaction(): TransferTransaction {
+ return TransferTransaction(
+ bankCode = transactionRequest.dccbCode,
+ branchCode = transactionRequest.branchCode.padStart(3,'0'),
+ cbsTellerId = teller.tellerId,
+ cbsTellerUserIdType = teller.userType,
+ queIdType = "5",
+ description = "${TransactionType.TRANSFER.code}For Checking",
+ priority = "1",
+ cbsTellerCapability = teller.capability,
+ txnScreenNo = TransactionType.TRANSFER.code.padStart(6, '0'),
+ txnAmt = transactionRequest.amount.toString(),
+ txnDate = date,
+ sourceAcctNo = transactionRequest.pacsCurrentAccountNumber,
+ destinationAcctNo = transactionRequest.linkedCBSAccountNumber,
+ narration = "TRF to member A/C for NEFT RTGS",
+ sourceTxnNo = "1045",
+ sourceStat = "A/P",
+ apiType = "OUTWARD_QUEUE_POSTING",
+ remitterName = transactionRequest.remitterName,
+ rrn = rrn + "1"
+ )
+
+ }
+
+ fun createNEFTTransaction(): NeftTransaction {
+ return NeftTransaction(
+ bankCode = transactionRequest.dccbCode,
+ branchCode = transactionRequest.branchCode.padStart(3,'0'),
+ cbsTellerId = teller.tellerId,
+ cbsTellerUserIdType = teller.userType,
+ queIdType = "5",
+ description = "${TransactionType.NEFT.code}For Checking",
+ priority = "1",
+ cbsTellerCapability = teller.capability,
+ txnScreenNo = TransactionType.NEFT.code.padStart(6, '0'),
+ txnAmt = transactionRequest.amount.toString(),
+ txnDate = date,
+ sourceAcctNo = transactionRequest.linkedCBSAccountNumber,
+ destinationAcctNo = transactionRequest.neftBeneficiaryAccountNumber,
+ narration = "TRF to member A/C for NEFT RTGS",
+ sourceTxnNo = TransactionType.NEFT.code,
+ sourceStat = "A/P",
+ apiType = "OUTWARD_QUEUE_POSTING",
+ remitterName = transactionRequest.remitterName,
+ ifscCode = transactionRequest.ifscCode,
+ rrn = rrn + "2"
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/TransactionResponse.kt b/src/main/kotlin/TransactionResponse.kt
new file mode 100644
index 0000000..bb17692
--- /dev/null
+++ b/src/main/kotlin/TransactionResponse.kt
@@ -0,0 +1,11 @@
+
+import kotlinx.serialization.Serializable
+
+
+@Serializable
+data class TransactionResponse(
+ val status: String,
+ val message: String,
+ val response: ResponseData,
+ val error: String
+)
diff --git a/src/main/kotlin/dao/TellerDao.kt b/src/main/kotlin/dao/TellerDao.kt
new file mode 100644
index 0000000..03afb18
--- /dev/null
+++ b/src/main/kotlin/dao/TellerDao.kt
@@ -0,0 +1,46 @@
+package dao
+
+import model.Teller
+
+class TellerDao {
+
+ private val tellerMap = mapOf(
+ "0016" to mapOf(
+ "008" to "118"
+ ),
+ "0012" to mapOf(
+ "008" to "8",
+ "022" to "22",
+ "012" to "12",
+ "014" to "14",
+ "003" to "1003",
+ "015" to "15",
+ "013" to "13",
+ "018" to "18",
+ "001" to "1001",
+ "004" to "4",
+ "017" to "1234",
+ "005" to "5",
+ "011" to "11",
+ "020" to "1234",
+ "021" to "1234",
+ "016" to "016",
+ "009" to "9",
+ "010" to "10",
+ "007" to "7",
+ "006" to "6"
+ )
+
+ )
+
+ fun getTeller(dccbCode: String, branchCode: String): Teller? {
+ val branchList = tellerMap[dccbCode] ?: return null
+ val tellerId = branchList[branchCode] ?: return null
+ val teller = Teller(
+ tellerId,
+ dccbCode,
+ branchCode
+ )
+ return teller
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/dao/TransactionDao.kt b/src/main/kotlin/dao/TransactionDao.kt
new file mode 100644
index 0000000..7d2b7af
--- /dev/null
+++ b/src/main/kotlin/dao/TransactionDao.kt
@@ -0,0 +1,101 @@
+package dao
+
+import model.TransactionRequest
+import java.sql.DriverManager
+import java.sql.ResultSet
+import java.util.Properties
+
+class TransactionDao {
+ private val transactionRequestQuery = """
+ select txn_no,
+ trim(src_ac_no) AS src_ac_no,
+ trim(dest_ac_no) AS dest_ac_no,
+ ifsc_code,
+ txn_amt,
+ txn_date,
+ t.teller_id,
+ (case
+ when t.ifsc_code like 'WBSC%' then
+ 'FAILED'
+ else
+ 'RECEIVED'
+ end) AS status,
+ substr(regexp_replace(regexp_replace(upper(beneficiary_name),'[^A-Z0-9 ]',''),' {2,}',' '),1,35) AS beneficiary_name,
+ beneficiary_add,
+ t.pacs_id,
+ dccb_code,
+ TO_NUMBER(cbs_br_code) AS br_code,
+ substr(regexp_replace(regexp_replace(upper(remm_name),'[^A-Z0-9 ]',''),' {2,}',' '),1,35) AS remitter_name,
+ ipks_accno AS pacs_acc_no,
+ da.link_accno AS cbs_sb_acc_no,
+ 'pacs_db' AS db_name
+ from neft_rtgs_txn t
+ join dep_account da ON t.ipks_accno = da.key_1
+ where
+ t.txn_date = (select system_date from system_date)
+ and t.STATUS = 'A'
+ and t.bank_channel = 'SCB'
+ and da.link_accno IS NOT NULL
+ """.trimIndent()
+
+ fun getTransactionRequests(): List {
+ val prop = loadProp()
+
+ val dbHost = getProp(prop, "DB_HOST")
+ val dbPort = getProp(prop, "DB_PORT")
+ val dbName = getProp(prop, "DB_NAME")
+
+ val dbUrl = "jdbc:oracle:thin:@$dbHost:$dbPort:$dbName"
+
+ val dbUser = getProp(prop, "DB_USER")
+ val dbPassword = getProp(prop, "DB_PASSWORD")
+
+ val transactionList: List
+
+ DriverManager.getConnection(dbUrl, dbUser, dbPassword).use { connection ->
+ connection.prepareStatement(transactionRequestQuery).executeQuery().use {
+ transactionList = mapToObject(it)
+ }
+ }
+
+ return transactionList
+ }
+
+ private fun loadProp(): Properties {
+
+ val props = javaClass.classLoader.getResourceAsStream("application.properties").use {
+ Properties().apply { load(it) }
+ }
+ return props
+ }
+
+ private fun getProp(prop: Properties, key: String): String {
+ return prop.getProperty(key) ?: throw RuntimeException("property $prop not found")
+ }
+
+ private fun mapToObject(rs: ResultSet): List {
+ val list = mutableListOf()
+ while (rs.next()) {
+ val transactionRequest = TransactionRequest(
+ transactionNumber = rs.getString("txn_no"),
+ pacsCurrentAccountNumber = rs.getString("src_ac_no"),
+ neftBeneficiaryAccountNumber = rs.getString("dest_ac_no"),
+ ifscCode = rs.getString("ifsc_code"),
+ amount = rs.getString("txn_amt").toFloat(),
+ date = rs.getDate("txn_date").toLocalDate(),
+ tellerId = rs.getString("teller_id"),
+ status = rs.getString("status"),
+ beneficiaryName = rs.getString("beneficiary_name"),
+ beneficiaryAddress = rs.getString("beneficiary_add"),
+ pacsId = rs.getString("pacs_id"),
+ dccbCode = rs.getString("dccb_code").padStart(4, '0'),
+ branchCode = rs.getString("br_Code").padStart(3, '0'),
+ remitterName = rs.getString("remitter_name"),
+ pacsAccountNumber = rs.getString("pacs_acc_no"),
+ linkedCBSAccountNumber = rs.getString("cbs_sb_acc_no"),
+ )
+ list.add(transactionRequest)
+ }
+ return list
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/enums/TransactionType.kt b/src/main/kotlin/enums/TransactionType.kt
new file mode 100644
index 0000000..98adec3
--- /dev/null
+++ b/src/main/kotlin/enums/TransactionType.kt
@@ -0,0 +1,7 @@
+package enums
+
+enum class TransactionType(val code: String) {
+ TRANSFER("01045"),
+ NEFT("20066"),
+ RTGS("20035")
+}
diff --git a/src/main/kotlin/model/NeftTransaction.kt b/src/main/kotlin/model/NeftTransaction.kt
new file mode 100644
index 0000000..3da9e60
--- /dev/null
+++ b/src/main/kotlin/model/NeftTransaction.kt
@@ -0,0 +1,29 @@
+package model
+
+import kotlinx.serialization.Serializable
+import org.ipks.enums.TransactionType
+import org.ipks.model.Transaction
+
+@Serializable
+class NeftTransaction(
+ override val bankCode: String,
+ override val branchCode: String,
+ override val cbsTellerId: String,
+ override val cbsTellerUserIdType: String,
+ override val queIdType: String,
+ override val description: String,
+ override val priority: String,
+ override val cbsTellerCapability: String,
+ override val txnScreenNo: String,
+ override val txnAmt: String,
+ override val txnDate: String,
+ override val sourceAcctNo: String,
+ override val destinationAcctNo: String,
+ override val narration: String,
+ override val sourceTxnNo: String,
+ override val sourceStat: String,
+ override val apiType: String,
+ override val remitterName: String,
+ val ifscCode: String,
+ override val rrn: String
+) : Transaction
\ No newline at end of file
diff --git a/src/main/kotlin/model/Teller.kt b/src/main/kotlin/model/Teller.kt
new file mode 100644
index 0000000..22fe5d3
--- /dev/null
+++ b/src/main/kotlin/model/Teller.kt
@@ -0,0 +1,10 @@
+package model
+
+data class Teller(
+ val tellerId: String,
+ val password: String,
+ val branch: String,
+ val dccbCode: String = "",
+ val userType: String = "50",
+ val capability: String = "9"
+)
\ No newline at end of file
diff --git a/src/main/kotlin/model/Transaction.kt b/src/main/kotlin/model/Transaction.kt
new file mode 100644
index 0000000..0459efe
--- /dev/null
+++ b/src/main/kotlin/model/Transaction.kt
@@ -0,0 +1,23 @@
+package org.ipks.model
+
+interface Transaction {
+ val bankCode: String
+ val branchCode: String
+ val cbsTellerId: String
+ val cbsTellerUserIdType: String
+ val queIdType: String
+ val description: String
+ val priority: String
+ val cbsTellerCapability: String
+ val txnScreenNo: String
+ val txnAmt: String
+ val txnDate: String
+ val sourceAcctNo: String
+ val destinationAcctNo: String
+ val narration: String
+ val sourceTxnNo: String
+ val sourceStat: String
+ val apiType: String
+ val remitterName: String
+ val rrn: String
+}
diff --git a/src/main/kotlin/model/TransactionRequest.kt b/src/main/kotlin/model/TransactionRequest.kt
new file mode 100644
index 0000000..0b3bf43
--- /dev/null
+++ b/src/main/kotlin/model/TransactionRequest.kt
@@ -0,0 +1,27 @@
+package model
+
+import kotlinx.serialization.Serializable
+import org.ipks.enums.TransactionType
+import org.ipks.model.Transaction
+import java.time.LocalDate
+
+
+data class TransactionRequest(
+ val transactionNumber: String,
+ val pacsCurrentAccountNumber: String,
+ val neftBeneficiaryAccountNumber: String,
+ val ifscCode: String,
+ val amount: Float,
+ val date: LocalDate,
+ val tellerId: String,
+ val status: String,
+ val beneficiaryName: String,
+ val beneficiaryAddress: String?,
+ val pacsId: String,
+ val dccbCode: String,
+ val branchCode: String,
+ val remitterName: String,
+ val pacsAccountNumber: String,
+ val linkedCBSAccountNumber: String
+)
+
diff --git a/src/main/kotlin/model/TransferTransaction.kt b/src/main/kotlin/model/TransferTransaction.kt
new file mode 100644
index 0000000..a20e645
--- /dev/null
+++ b/src/main/kotlin/model/TransferTransaction.kt
@@ -0,0 +1,27 @@
+package model
+
+import kotlinx.serialization.Serializable
+import org.ipks.model.Transaction
+
+@Serializable
+class TransferTransaction(
+ override val bankCode: String,
+ override val branchCode: String,
+ override val cbsTellerId: String,
+ override val cbsTellerUserIdType: String,
+ override val queIdType: String,
+ override val description: String,
+ override val priority: String,
+ override val cbsTellerCapability: String,
+ override val txnScreenNo: String,
+ override val txnAmt: String,
+ override val txnDate: String,
+ override val sourceAcctNo: String,
+ override val destinationAcctNo: String,
+ override val narration: String,
+ override val sourceTxnNo: String,
+ override val sourceStat: String,
+ override val apiType: String,
+ override val remitterName: String,
+ override val rrn: String
+) : Transaction
\ No newline at end of file