gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: match payment initiations with bank ac


From: gnunet
Subject: [libeufin] branch master updated: match payment initiations with bank account transactions
Date: Thu, 18 Jun 2020 20:34:57 +0200

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository libeufin.

The following commit(s) were added to refs/heads/master by this push:
     new f54bd1b  match payment initiations with bank account transactions
f54bd1b is described below

commit f54bd1bc9f106d18ed5b562729f701bfd50eb372
Author: Florian Dold <florian.dold@gmail.com>
AuthorDate: Fri Jun 19 00:04:49 2020 +0530

    match payment initiations with bank account transactions
---
 nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt    | 34 +++++++++++-----------
 .../main/kotlin/tech/libeufin/nexus/Iso20022.kt    | 10 +++++--
 nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt  |  2 +-
 .../tech/libeufin/nexus/bankaccount/BankAccount.kt | 24 +++++++++++----
 nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt | 14 ++++-----
 5 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
index 366449b..2b7475a 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt
@@ -64,7 +64,7 @@ class TalerRequestedPaymentEntity(id: EntityID<Long>) : 
LongEntity(id) {
  * entries from the raw payments table.  Fixme: name should end with "-table".
  */
 object TalerIncomingPayments : LongIdTable() {
-    val payment = reference("payment", RawBankTransactionsTable)
+    val payment = reference("payment", NexusBankTransactionsTable)
     val reservePublicKey = text("reservePublicKey")
     val timestampMs = long("timestampMs")
     val incomingPaytoUri = text("incomingPaytoUri")
@@ -73,7 +73,7 @@ object TalerIncomingPayments : LongIdTable() {
 class TalerIncomingPaymentEntity(id: EntityID<Long>) : LongEntity(id) {
     companion object : 
LongEntityClass<TalerIncomingPaymentEntity>(TalerIncomingPayments)
 
-    var payment by RawBankTransactionEntity referencedOn 
TalerIncomingPayments.payment
+    var payment by NexusBankTransactionEntity referencedOn 
TalerIncomingPayments.payment
     var reservePublicKey by TalerIncomingPayments.reservePublicKey
     var timestampMs by TalerIncomingPayments.timestampMs
     var incomingPaytoUri by TalerIncomingPayments.incomingPaytoUri
@@ -104,7 +104,7 @@ class NexusBankMessageEntity(id: EntityID<Int>) : 
IntEntity(id) {
  * This table contains history "elements" as returned by the bank from a
  * CAMT message.
  */
-object RawBankTransactionsTable : LongIdTable() {
+object NexusBankTransactionsTable : LongIdTable() {
     /**
      * Identifier for the transaction that is unique among all transactions of 
the account.
      * The scheme for this identifier is the accounts transaction 
identification scheme.
@@ -138,7 +138,7 @@ object RawBankTransactionsTable : LongIdTable() {
     /**
      * Another, later transaction that updates the status of the current 
transaction.
      */
-    val updatedBy = optReference("updatedBy", RawBankTransactionsTable)
+    val updatedBy = optReference("updatedBy", NexusBankTransactionsTable)
 
     /**
      * Full details of the transaction in JSON format.
@@ -146,16 +146,16 @@ object RawBankTransactionsTable : LongIdTable() {
     val transactionJson = text("transactionJson")
 }
 
-class RawBankTransactionEntity(id: EntityID<Long>) : LongEntity(id) {
-    companion object : 
LongEntityClass<RawBankTransactionEntity>(RawBankTransactionsTable)
-    var currency by RawBankTransactionsTable.currency
-    var amount by RawBankTransactionsTable.amount
-    var status by RawBankTransactionsTable.status
-    var creditDebitIndicator by RawBankTransactionsTable.creditDebitIndicator
-    var bankAccount by NexusBankAccountEntity referencedOn 
RawBankTransactionsTable.bankAccount
-    var transactionJson by RawBankTransactionsTable.transactionJson
-    var accountTransactionId by RawBankTransactionsTable.accountTransactionId
-    val updatedBy by RawBankTransactionEntity optionalReferencedOn 
RawBankTransactionsTable.updatedBy
+class NexusBankTransactionEntity(id: EntityID<Long>) : LongEntity(id) {
+    companion object : 
LongEntityClass<NexusBankTransactionEntity>(NexusBankTransactionsTable)
+    var currency by NexusBankTransactionsTable.currency
+    var amount by NexusBankTransactionsTable.amount
+    var status by NexusBankTransactionsTable.status
+    var creditDebitIndicator by NexusBankTransactionsTable.creditDebitIndicator
+    var bankAccount by NexusBankAccountEntity referencedOn 
NexusBankTransactionsTable.bankAccount
+    var transactionJson by NexusBankTransactionsTable.transactionJson
+    var accountTransactionId by NexusBankTransactionsTable.accountTransactionId
+    val updatedBy by NexusBankTransactionEntity optionalReferencedOn 
NexusBankTransactionsTable.updatedBy
 }
 
 /**
@@ -184,7 +184,7 @@ object PaymentInitiationsTable : LongIdTable() {
      * Points at the raw transaction witnessing that this
      * initiated payment was successfully performed.
      */
-    val rawConfirmation = reference("rawConfirmation", 
RawBankTransactionsTable).nullable()
+    val confirmationTransaction = reference("rawConfirmation", 
NexusBankTransactionsTable).nullable()
 }
 
 class PaymentInitiationEntity(id: EntityID<Long>) : LongEntity(id) {
@@ -204,7 +204,7 @@ class PaymentInitiationEntity(id: EntityID<Long>) : 
LongEntity(id) {
     var paymentInformationId by PaymentInitiationsTable.paymentInformationId
     var messageId by PaymentInitiationsTable.messageId
     var instructionId by PaymentInitiationsTable.instructionId
-    var rawConfirmation by RawBankTransactionEntity optionalReferencedOn 
PaymentInitiationsTable.rawConfirmation
+    var confirmationTransaction by NexusBankTransactionEntity 
optionalReferencedOn PaymentInitiationsTable.confirmationTransaction
 }
 
 /**
@@ -343,7 +343,7 @@ fun dbCreateTables(dbName: String) {
             PaymentInitiationsTable,
             EbicsSubscribersTable,
             NexusBankAccountsTable,
-            RawBankTransactionsTable,
+            NexusBankTransactionsTable,
             TalerIncomingPayments,
             TalerRequestedPayments,
             NexusBankConnectionsTable,
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
index 5c88077..ffba9f4 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt
@@ -194,7 +194,9 @@ data class AmountDetails(
 
 @JsonInclude(JsonInclude.Include.NON_NULL)
 data class References(
-    val endToEndIdentification: String?
+    val endToEndIdentification: String? = null,
+    val paymentInformationIdentification: String? = null,
+    val messageIdentification: String? = null
 )
 
 /**
@@ -444,9 +446,11 @@ private fun 
XmlElementDestructor.extractTransactionDetails(): List<TransactionDe
                 } ?: AmountDetails(null, null),
                 references = maybeUniqueChildNamed("Refs") {
                     References(
-                        endToEndIdentification = 
maybeUniqueChildNamed("EndToEndId") { it.textContent }
+                        endToEndIdentification = 
maybeUniqueChildNamed("EndToEndId") { it.textContent },
+                        messageIdentification = maybeUniqueChildNamed("MsgId") 
{ it.textContent },
+                        paymentInformationIdentification = 
maybeUniqueChildNamed("PmtInfId") { it.textContent }
                     )
-                } ?: References(null),
+                } ?: References(),
                 unstructuredRemittanceInformation = 
maybeUniqueChildNamed("RmtInf") {
                     requireUniqueChildNamed("Ustrd") { it.textContent }
                 } ?: ""
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index 8de9a0d..f70cae4 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -662,7 +662,7 @@ fun serverMain(dbName: String) {
                 val ret = Transactions()
                 transaction {
                     authenticateRequest(call.request).id.value
-                    RawBankTransactionEntity.all().map {
+                    NexusBankTransactionEntity.all().map {
                         val tx = 
jacksonObjectMapper().readValue(it.transactionJson, BankTransaction::class.java)
                         ret.transactions.add(tx)
                     }
diff --git 
a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
index 16a17c3..acd128d 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt
@@ -24,7 +24,6 @@ import io.ktor.client.HttpClient
 import io.ktor.http.HttpStatusCode
 import org.jetbrains.exposed.sql.SortOrder
 import org.jetbrains.exposed.sql.and
-import org.jetbrains.exposed.sql.not
 import org.jetbrains.exposed.sql.transactions.transaction
 import org.w3c.dom.Document
 import tech.libeufin.nexus.*
@@ -90,12 +89,12 @@ suspend fun submitAllPreparedPayments(httpClient: 
HttpClient) {
 /**
  * Check if the transaction is already found in the database.
  */
-private fun findDuplicate(bankAccountId: String, acctSvcrRef: String): 
RawBankTransactionEntity? {
+private fun findDuplicate(bankAccountId: String, acctSvcrRef: String): 
NexusBankTransactionEntity? {
     // FIXME: make this generic depending on transaction identification scheme
     val ati = "AcctSvcrRef:$acctSvcrRef"
     return transaction {
-        RawBankTransactionEntity.find {
-            (RawBankTransactionsTable.accountTransactionId eq ati) and 
(RawBankTransactionsTable.bankAccount eq bankAccountId)
+        NexusBankTransactionEntity.find {
+            (NexusBankTransactionsTable.accountTransactionId eq ati) and 
(NexusBankTransactionsTable.bankAccount eq bankAccountId)
         }.firstOrNull()
     }
 }
@@ -126,7 +125,7 @@ fun processCamtMessage(
                 break
             }
 
-            val rawEntity = RawBankTransactionEntity.new {
+            val rawEntity = NexusBankTransactionEntity.new {
                 bankAccount = acct
                 accountTransactionId = "AcctSvcrRef:$acctSvcrRef"
                 amount = tx.amount
@@ -135,7 +134,22 @@ fun processCamtMessage(
                 creditDebitIndicator = tx.creditDebitIndicator.name
                 status = tx.status
             }
+            rawEntity.flush()
             if (tx.creditDebitIndicator == CreditDebitIndicator.DBIT) {
+                val t0 = tx.details.getOrNull(0)
+                val msgId = t0?.references?.messageIdentification
+                val pmtInfId = t0?.references?.paymentInformationIdentification
+                if (t0 != null && msgId != null && pmtInfId != null) {
+                    val paymentInitiation = PaymentInitiationEntity.find {
+                        (PaymentInitiationsTable.messageId eq msgId) and
+                                (PaymentInitiationsTable.bankAccount eq 
acct.id) and
+                                (PaymentInitiationsTable.paymentInformationId 
eq pmtInfId)
+
+                    }.firstOrNull()
+                    if (paymentInitiation != null) {
+                        paymentInitiation.confirmationTransaction = rawEntity
+                    }
+                }
                 // FIXME: find matching PaymentInitiation by 
PaymentInformationID, message ID or whatever is present
             }
         }
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
index 4741ecb..2b4dbc2 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
@@ -350,7 +350,7 @@ private suspend fun talerAddIncoming(call: ApplicationCall, 
httpClient: HttpClie
 }
 
 
-private fun ingestIncoming(payment: RawBankTransactionEntity, txDtls: 
TransactionDetails) {
+private fun ingestIncoming(payment: NexusBankTransactionEntity, txDtls: 
TransactionDetails) {
     val subject = txDtls.unstructuredRemittanceInformation
     val debtorName = txDtls.relatedParties.debtor?.name
     if (debtorName == null) {
@@ -407,14 +407,14 @@ fun ingestTalerTransactions() {
         logger.debug("Ingesting transactions for Taler facade 
${facade.id.value}")
         val facadeState = getTalerFacadeState(facade.id.value)
         var lastId = facadeState.highestSeenMsgID
-        RawBankTransactionEntity.find {
+        NexusBankTransactionEntity.find {
             /** Those with exchange bank account involved */
-            RawBankTransactionsTable.bankAccount eq subscriberAccount.id.value 
and
+            NexusBankTransactionsTable.bankAccount eq 
subscriberAccount.id.value and
                     /** Those that are booked */
-                    (RawBankTransactionsTable.status eq 
TransactionStatus.BOOK) and
+                    (NexusBankTransactionsTable.status eq 
TransactionStatus.BOOK) and
                     /** Those that came later than the latest processed 
payment */
-                    (RawBankTransactionsTable.id.greater(lastId))
-        }.orderBy(Pair(RawBankTransactionsTable.id, SortOrder.ASC)).forEach {
+                    (NexusBankTransactionsTable.id.greater(lastId))
+        }.orderBy(Pair(NexusBankTransactionsTable.id, SortOrder.ASC)).forEach {
             // Incoming payment.
             val tx = jacksonObjectMapper().readValue(it.transactionJson, 
BankTransaction::class.java)
             if (tx.isBatch) {
@@ -464,7 +464,7 @@ private suspend fun historyOutgoing(call: ApplicationCall) {
             startCmpOp
         }.orderTaler(delta)
         reqPaymentsWithUnconfirmed.forEach {
-            if (it.preparedPayment.rawConfirmation != null) {
+            if (it.preparedPayment.confirmationTransaction != null) {
                 reqPayments.add(it)
             }
         }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]