libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

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:
Mnexus/src/main/kotlin/tech/libeufin/nexus/DB.kt | 2--
Mnexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt | 65++++++++++++++++++++++++++++++++++++-----------------------------
Mnexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 17+++++++++++++++++
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)