summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/DB.kt34
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/Iso20022.kt10
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt2
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/bankaccount/BankAccount.kt24
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt14
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 366449bf..2b7475ab 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 5c880775..ffba9f4b 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 8de9a0d2..f70cae41 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 16a17c34..acd128da 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 4741ecbc..2b4dbc2a 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)
}
}