commit c64828e98d72b28a7f1137c9f21fd3fe3a3c9048
parent 437729559aac3ccda0082e8f623454f26a554537
Author: Florian Dold <florian.dold@gmail.com>
Date: Sun, 24 May 2020 22:25:29 +0530
start splitting camt download/processing phases
Diffstat:
3 files changed, 53 insertions(+), 31 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
@@ -92,7 +92,6 @@ class TalerIncomingPaymentEntity(id: EntityID<Long>) : LongEntity(id) {
*/
object RawBankTransactionsTable : LongIdTable() {
val nexusUser = reference("nexusUser", NexusUsersTable)
- val sourceFileName = text("sourceFileName") /* ZIP entry's name */
val unstructuredRemittanceInformation = text("unstructuredRemittanceInformation")
val transactionType = text("transactionType") /* DBIT or CRDT */
val currency = text("currency")
@@ -108,7 +107,6 @@ object RawBankTransactionsTable : LongIdTable() {
class RawBankTransactionEntity(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<RawBankTransactionEntity>(RawBankTransactionsTable)
- var sourceFileName by RawBankTransactionsTable.sourceFileName
var unstructuredRemittanceInformation by RawBankTransactionsTable.unstructuredRemittanceInformation
var transactionType by RawBankTransactionsTable.transactionType
var currency by RawBankTransactionsTable.currency
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
@@ -6,6 +6,7 @@ import io.ktor.request.ApplicationRequest
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.transactions.transaction
import org.joda.time.DateTime
+import org.w3c.dom.Document
import tech.libeufin.util.*
import tech.libeufin.util.ebics_h004.EbicsTypes
import java.security.interfaces.RSAPublicKey
@@ -101,6 +102,40 @@ fun getEbicsSubscriberDetails(userId: String, transportId: String): EbicsClientS
return getEbicsSubscriberDetailsInternal(subscriber)
}
+// FIXME(dold): This should put stuff under *fixed* bank account, not some we find via the IBAN.
+fun processCamtMessage(
+ userId: String,
+ camt53doc: Document
+) {
+ transaction {
+ val user = NexusUserEntity.findById(userId)
+ if (user == null) {
+ throw NexusError(HttpStatusCode.NotFound, "user not found")
+ }
+ RawBankTransactionEntity.new {
+ bankAccount = getBankAccountFromIban(
+ camt53doc.pickString(
+ "//*[local-name()='Stmt']/*[local-name()='Acct']/*[local-name()='Id']/*[local-name()='IBAN']"
+ )
+ )
+ unstructuredRemittanceInformation =
+ camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Ustrd']")
+ transactionType = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='CdtDbtInd']")
+ currency = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']/@Ccy")
+ amount = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']")
+ status = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Sts']")
+ bookingDate =
+ parseDashedDate(camt53doc.pickString("//*[local-name()='BookgDt']//*[local-name()='Dt']")).millis
+ nexusUser = user
+ counterpartIban =
+ camt53doc.pickString("//*[local-name()='${if (this.transactionType == "DBIT") "CdtrAcct" else "DbtrAcct"}']//*[local-name()='IBAN']")
+ counterpartName =
+ camt53doc.pickString("//*[local-name()='RltdPties']//*[local-name()='${if (this.transactionType == "DBIT") "Cdtr" else "Dbtr"}']//*[local-name()='Nm']")
+ counterpartBic = camt53doc.pickString("//*[local-name()='RltdAgts']//*[local-name()='BIC']")
+ }
+ }
+}
+
suspend fun downloadAndPersistC5xEbics(
historyType: String,
client: HttpClient,
@@ -127,36 +162,8 @@ suspend fun downloadAndPersistC5xEbics(
is EbicsDownloadSuccessResult -> {
response.orderData.unzipWithLambda {
logger.debug("Camt entry: ${it.second}")
- val fileName = it.first
val camt53doc = XMLUtil.parseStringIntoDom(it.second)
- transaction {
- val user = NexusUserEntity.findById(userId)
- if (user == null) {
- throw NexusError(HttpStatusCode.NotFound, "user not found")
- }
- RawBankTransactionEntity.new {
- bankAccount = getBankAccountFromIban(
- camt53doc.pickString(
- "//*[local-name()='Stmt']/*[local-name()='Acct']/*[local-name()='Id']/*[local-name()='IBAN']"
- )
- )
- sourceFileName = fileName
- unstructuredRemittanceInformation =
- camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Ustrd']")
- transactionType = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='CdtDbtInd']")
- currency = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']/@Ccy")
- amount = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']")
- status = camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Sts']")
- bookingDate =
- parseDashedDate(camt53doc.pickString("//*[local-name()='BookgDt']//*[local-name()='Dt']")).millis
- nexusUser = user
- counterpartIban =
- camt53doc.pickString("//*[local-name()='${if (this.transactionType == "DBIT") "CdtrAcct" else "DbtrAcct"}']//*[local-name()='IBAN']")
- counterpartName =
- camt53doc.pickString("//*[local-name()='RltdPties']//*[local-name()='${if (this.transactionType == "DBIT") "Cdtr" else "Dbtr"}']//*[local-name()='Nm']")
- counterpartBic = camt53doc.pickString("//*[local-name()='RltdAgts']//*[local-name()='BIC']")
- }
- }
+ processCamtMessage(userId, camt53doc)
}
}
is EbicsDownloadBankErrorResult -> {
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -769,6 +769,23 @@ fun serverMain() {
call.respond(object {})
}
+ post("/bank-connections/{connid}/ebics/fetch-c52") {
+ val paramsJson = call.receiveOrNull<EbicsStandardOrderParamsJson>()
+ val orderParams = if (paramsJson == null) {
+ EbicsStandardOrderParams()
+ } else {
+ paramsJson.toOrderParams()
+ }
+ val subscriberDetails = transaction {
+ val user = authenticateRequest(call.request)
+ val conn = requireBankConnection(call, "connid")
+ if (conn.type != "ebics") {
+ throw NexusError(HttpStatusCode.BadRequest, "bank connection is not of type 'ebics'")
+ }
+ getEbicsSubscriberDetails(user.id.value, conn.id.value)
+ }
+ }
+
post("/bank-connections/{connid}/ebics/send-ini") {
val subscriber = transaction {
val user = authenticateRequest(call.request)