libeufin

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

commit 22045f1f17d4683b1b068ccccca3dacf560a0627
parent 939de8fbe7434c3f0bb045205eeab5dbf1720710
Author: Florian Dold <florian.dold@gmail.com>
Date:   Tue, 16 Jun 2020 17:53:44 +0530

look for old transaction to supersede

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/DB.kt | 8+++++++-
Mnexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt | 22++++++++++------------
2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt @@ -147,7 +147,12 @@ object RawBankTransactionsTable : LongIdTable() { /** * Booked / pending / informational. */ - val status = text("status") + val status = enumerationByName("status", 16, TransactionStatus::class) + + /** + * Another, later transaction that updates the status of the current transaction. + */ + val updatedBy = optReference("updatedBy", RawBankTransactionsTable) /** * Full details of the transaction in JSON format. @@ -165,6 +170,7 @@ class RawBankTransactionEntity(id: EntityID<Long>) : LongEntity(id) { var bankAccount by NexusBankAccountEntity referencedOn RawBankTransactionsTable.bankAccount var transactionJson by RawBankTransactionsTable.transactionJson var accountTransactionId by RawBankTransactionsTable.accountTransactionId + val updatedBy by RawBankTransactionEntity optionalReferencedOn RawBankTransactionsTable.updatedBy } /** diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt @@ -20,12 +20,9 @@ package tech.libeufin.nexus import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import io.ktor.client.HttpClient import io.ktor.http.HttpStatusCode -import io.ktor.request.ApplicationRequest import org.jetbrains.exposed.sql.SortOrder import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.statements.api.ExposedBlob import org.jetbrains.exposed.sql.transactions.transaction import org.w3c.dom.Document import tech.libeufin.util.* @@ -103,14 +100,13 @@ fun getEbicsSubscriberDetailsInternal(subscriber: EbicsSubscriberEntity): EbicsC /** * Check if the transaction is already found in the database. */ -private fun isDuplicate(acctSvcrRef: String): Boolean { +private fun findDuplicate(bankAccountId: String, acctSvcrRef: String): RawBankTransactionEntity? { // FIXME: make this generic depending on transaction identification scheme val ati = "AcctSvcrRef:$acctSvcrRef" return transaction { - val res = RawBankTransactionEntity.find { - RawBankTransactionsTable.accountTransactionId eq ati + RawBankTransactionEntity.find { + (RawBankTransactionsTable.accountTransactionId eq ati) and (RawBankTransactionsTable.bankAccount eq bankAccountId) }.firstOrNull() - res != null } } @@ -126,16 +122,18 @@ fun processCamtMessage( } val transactions = getTransactions(camtDoc) logger.info("found ${transactions.size} transactions") - for (tx in transactions) { + txloop@for (tx in transactions) { val acctSvcrRef = tx.accountServicerReference if (acctSvcrRef == null) { // FIXME(dold): Report this! logger.error("missing account servicer reference in transaction") continue } - if (isDuplicate(acctSvcrRef)) { - logger.info("Processing a duplicate, not storing it.") - return@transaction + val duplicate = findDuplicate(bankAccountId, acctSvcrRef) + if (duplicate != null) { + // FIXME(dold): See if an old transaction needs to be superseded by this one + // https://bugs.gnunet.org/view.php?id=6381 + break } RawBankTransactionEntity.new { bankAccount = acct @@ -144,7 +142,7 @@ fun processCamtMessage( currency = tx.currency transactionJson = jacksonObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(tx) creditDebitIndicator = tx.creditDebitIndicator.name - status = tx.status.name + status = tx.status } } }