libeufin

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

commit 7ccac24e29bd825ac2e0e721226ccabde6d947cc
parent 26ffdc3a51b6b9c8544e28ee07e4a04382dd5698
Author: MS <ms@taler.net>
Date:   Tue,  5 Sep 2023 09:32:59 +0200

addressing #7275

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/Anastasis.kt | 42++++++++++++++++++++++++++++++++----------
Mnexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt | 29++++++++++++++++-------------
2 files changed, 48 insertions(+), 23 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Anastasis.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Anastasis.kt @@ -21,7 +21,6 @@ data class AnastasisIncomingBankTransaction( val row_id: Long, val date: GnunetTimestamp, // timestamp val amount: String, - val credit_account: String, // payto form, val debit_account: String, val subject: String ) @@ -76,6 +75,11 @@ fun anastasisFilter(payment: NexusBankTransactionEntity, txDtls: TransactionDeta } } +data class AnastasisIncomingTransactions( + val credit_account: String, + val incoming_transactions: MutableList<AnastasisIncomingBankTransaction> +) + // Handle a /taler-wire-gateway/history/incoming request. private suspend fun historyIncoming(call: ApplicationCall) { val facadeId = expectNonNull(call.parameters["fcid"]) @@ -90,16 +94,29 @@ private suspend fun historyIncoming(call: ApplicationCall) { val delta: Int = try { param.toInt() } catch (e: Exception) { throw EbicsProtocolError(HttpStatusCode.BadRequest, "'${param}' is not Int") } - val start: Long = handleStartArgument(call.request.queryParameters["start"], delta) + val start: Long = handleStartArgument( + call.request.queryParameters["start"], + delta + ) val history = object { val incoming_transactions: MutableList<AnastasisIncomingBankTransaction> = mutableListOf() + } val startCmpOp = getComparisonOperator(delta, start, AnastasisIncomingPaymentsTable) - transaction { + val incomingTransactionsResp = transaction { val orderedPayments = AnastasisIncomingPaymentEntity.find { startCmpOp }.orderTaler(delta) // Taler and Anastasis have same ordering policy. Fixme: find better function's name? if (orderedPayments.isNotEmpty()) { + val creditBankAccountObj = orderedPayments[0] + val ret = AnastasisIncomingTransactions( + credit_account = buildIbanPaytoUri( + creditBankAccountObj.payment.bankAccount.iban, + creditBankAccountObj.payment.bankAccount.bankCode, + creditBankAccountObj.payment.bankAccount.accountHolder, + ), + incoming_transactions = mutableListOf() + ) orderedPayments.subList(0, min(abs(delta), orderedPayments.size)).forEach { history.incoming_transactions.add( AnastasisIncomingBankTransaction( @@ -108,18 +125,23 @@ private suspend fun historyIncoming(call: ApplicationCall) { row_id = it.id.value, amount = "${it.payment.currency}:${it.payment.amount}", subject = it.subject, - credit_account = buildIbanPaytoUri( - it.payment.bankAccount.iban, - it.payment.bankAccount.bankCode, - it.payment.bankAccount.accountHolder, - ), debit_account = it.debtorPaytoUri ) ) } - } + return@transaction ret + } else null } - return call.respond(TextContent(customConverter(history), ContentType.Application.Json)) + if (incomingTransactionsResp == null) { + call.respond(HttpStatusCode.NoContent) + return + } + return call.respond( + TextContent( + customConverter(incomingTransactionsResp), + ContentType.Application.Json + ) + ) } fun anastasisFacadeRoutes(route: Route) { diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt @@ -81,13 +81,13 @@ data class TalerIncomingBankTransaction( val row_id: Long, val date: GnunetTimestamp, // timestamp val amount: String, - val credit_account: String, // payto form, val debit_account: String, val reserve_pub: String ) data class TalerIncomingHistory( - var incoming_transactions: MutableList<TalerIncomingBankTransaction> = mutableListOf() + var incoming_transactions: MutableList<TalerIncomingBankTransaction> = mutableListOf(), + val credit_account: String ) data class TalerOutgoingBankTransaction( @@ -483,12 +483,12 @@ private suspend fun historyIncoming(call: ApplicationCall) { throw EbicsProtocolError(HttpStatusCode.BadRequest, "'${param}' is not Int") } val start: Long = handleStartArgument(call.request.queryParameters["start"], delta) - val history = TalerIncomingHistory() + val facadeBankAccount = getFacadeBankAccount(facadeId) val startCmpOp = getComparisonOperator(delta, start, TalerIncomingPaymentsTable) val listenHandle: PostgresListenHandle? = if (isPostgres() && longPollTimeout != null) { val notificationChannelName = buildChannelName( NotificationsChannelDomains.LIBEUFIN_TALER_INCOMING, - getFacadeBankAccount(facadeId).iban + facadeBankAccount.iban ) val handle = PostgresListenHandle(channelName = notificationChannelName) handle.postgresListen() @@ -534,7 +534,14 @@ private suspend fun historyIncoming(call: ApplicationCall) { * proceeds to the response (== resultOrWait.first IS EFFECTIVE). */ val maybeNewPayments = result - if (maybeNewPayments.isNotEmpty()) { + val resp = if (maybeNewPayments.isNotEmpty()) { + val history = TalerIncomingHistory( + credit_account = buildIbanPaytoUri( + facadeBankAccount.iban, + facadeBankAccount.bankCode, + facadeBankAccount.accountHolder, + ) + ) transaction { maybeNewPayments.subList( 0, @@ -547,24 +554,20 @@ private suspend fun historyIncoming(call: ApplicationCall) { row_id = it.id.value, amount = "${it.payment.currency}:${it.payment.amount}", reserve_pub = it.reservePublicKey, - credit_account = buildIbanPaytoUri( - it.payment.bankAccount.iban, - it.payment.bankAccount.bankCode, - it.payment.bankAccount.accountHolder, - ), debit_account = it.debtorPaytoUri ) ) } } - } - if (history.incoming_transactions.size == 0) { + history + } else null + if (resp == null) { call.respond(HttpStatusCode.NoContent) return } return call.respond( status = HttpStatusCode.OK, - TextContent(customConverter(history), ContentType.Application.Json) + TextContent(customConverter(resp), ContentType.Application.Json) ) }