gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] 03/04: balance (1) and debit limit (2)


From: gnunet
Subject: [libeufin] 03/04: balance (1) and debit limit (2)
Date: Tue, 20 Dec 2022 17:29:42 +0100

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

ms pushed a commit to branch master
in repository libeufin.

commit ffd714d263da95e59088906e1d7fe5165e39985c
Author: MS <ms@taler.net>
AuthorDate: Tue Dec 20 17:25:48 2022 +0100

    balance (1) and debit limit (2)
    
    1.  Get balances using the last statement as the
    base, then optionally adding pending transactions
    to it.
    
    2.  Enforce debit limit for wire transfers and
      Taler withdrawals.
---
 .../tech/libeufin/sandbox/EbicsProtocolBackend.kt  |  58 +++---
 .../main/kotlin/tech/libeufin/sandbox/Helpers.kt   | 109 +-----------
 .../src/main/kotlin/tech/libeufin/sandbox/Main.kt  |  49 +++---
 .../kotlin/tech/libeufin/sandbox/bankAccount.kt    | 194 +++++++++++++++++----
 sandbox/src/test/kotlin/BalanceTest.kt             |   5 +-
 5 files changed, 217 insertions(+), 198 deletions(-)

diff --git 
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 3d1227ae..8f2fd3b9 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -500,22 +500,6 @@ fun buildCamtString(
     )
 }
 
-/**
- * The last balance is the one accounted in the bank account's
- * last statement.
- */
-fun getLastBalance(
-    bankAccount: BankAccountEntity,
-): BigDecimal {
-    val lastStatement = BankAccountStatementEntity.find {
-        BankAccountStatementsTable.bankAccount eq bankAccount.id
-    }.lastOrNull()
-    val lastBalance = if (lastStatement == null) {
-        BigDecimal.ZERO
-    } else { BigDecimal(lastStatement.balanceClbd) }
-    return lastBalance
-}
-
 /**
  * Builds CAMT response.
  *
@@ -533,28 +517,46 @@ private fun constructCamtResponse(
         if (dateRange != null)
             throw EbicsOrderParamsIgnored("C52 does not support date ranges.")
         val history = mutableListOf<RawPayment>()
-        val lastBalance = transaction {
+        transaction {
             BankAccountFreshTransactionEntity.all().forEach {
                 if (it.transactionRef.account.label == bankAccount.label) {
                     history.add(getHistoryElementFromTransactionRow(it))
                 }
             }
-            getLastBalance(bankAccount)
         }
-        if (history.size == 0)
-            throw EbicsNoDownloadDataAvailable()
-
-        val freshBalance = balanceForAccount(
-            history = history,
-            baseBalance = lastBalance
-        )
-
+        if (history.size == 0) throw EbicsNoDownloadDataAvailable()
+
+        /**
+         * PRCD balance: balance mentioned in the last statement.  This
+         * will be normally zero, because statements need to be explicitly 
created.
+         *
+         * CLBD balance: PRCD + transactions accounted in the current C52.
+         * Alternatively, that could be changed into: PRCD + all the pending
+         * transactions.  This way, the CLBD balance would closer reflect the
+         * latest (pending) activities.
+         */
+        val prcdBalance = getBalance(bankAccount, withPending = false)
+        val clbdBalance = run {
+            var base = prcdBalance
+            history.forEach { tx ->
+                when (tx.direction) {
+                    "DBIT" -> base -= parseDecimal(tx.amount)
+                    "CRDT" -> base += parseDecimal(tx.amount)
+                    else -> {
+                        logger.error("Transaction with subject '${tx.subject}' 
is " +
+                                "inconsistent: neither DBIT nor CRDT")
+                        throw internalServerError("Transactions internal 
error.")
+                    }
+                }
+            }
+            base
+        }
         val camtData = buildCamtString(
             type,
             bankAccount.iban,
             history,
-            balancePrcd = lastBalance,
-            balanceClbd = freshBalance
+            balancePrcd = prcdBalance,
+            balanceClbd = clbdBalance
         )
         val paymentsList: String = if (logger.isDebugEnabled) {
             var ret = " It includes the payments:"
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
index f7650af5..ed17bc5a 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
@@ -203,117 +203,10 @@ fun getDefaultDemobank(): DemobankConfigEntity {
     )
 }
 
-fun wireTransfer(
-    debitAccount: String,
-    creditAccount: String,
-    demobank: String,
-    subject: String,
-    amount: String, // $currency:x.y
-    pmtInfId: String? = null
-): String {
-    val args: Triple<BankAccountEntity, BankAccountEntity, 
DemobankConfigEntity> = transaction {
-        val debitAccountDb = BankAccountEntity.find {
-            BankAccountsTable.label eq debitAccount
-        }.firstOrNull() ?: throw SandboxError(
-            HttpStatusCode.NotFound,
-            "Debit account '$debitAccount' not found"
-        )
-        val creditAccountDb = BankAccountEntity.find {
-            BankAccountsTable.label eq creditAccount
-        }.firstOrNull() ?: throw SandboxError(
-            HttpStatusCode.NotFound,
-            "Credit account '$creditAccount' not found"
-        )
-        val demoBank = DemobankConfigEntity.find {
-            DemobankConfigsTable.name eq demobank
-        }.firstOrNull() ?: throw SandboxError(
-            HttpStatusCode.NotFound,
-            "Demobank '$demobank' not found"
-        )
-
-        Triple(debitAccountDb, creditAccountDb, demoBank)
-    }
-
-    /**
-     * Only validating the amount.  Actual check on the
-     * currency will be done by the callee below.
-     */
-    val amountObj = parseAmount(amount)
-    return wireTransfer(
-        debitAccount = args.first,
-        creditAccount = args.second,
-        demobank = args.third,
-        subject = subject,
-        amount = amountObj.amount.toPlainString(),
-        pmtInfId
-    )
-}
-/**
- * Book a CRDT and a DBIT transaction and return the unique reference thereof.
- *
- * At the moment there is redundancy because all the creditor / debtor details
- * are contained (directly or indirectly) already in the BankAccount 
parameters.
- *
- * This is kept both not to break the existing tests and to allow future 
versions
- * where one party of the transaction is not a customer of the running Sandbox.
- */
-
-fun wireTransfer(
-    debitAccount: BankAccountEntity,
-    creditAccount: BankAccountEntity,
-    demobank: DemobankConfigEntity,
-    subject: String,
-    amount: String,
-    pmtInfId: String? = null
-): String {
-    // sanity check on the amount, no currency allowed here.
-    val checkAmount = parseDecimal(amount)
-    if (checkAmount == BigDecimal.ZERO) throw badRequest("Wire transfers of 
zero not possible.")
-    val timeStamp = getUTCnow().toInstant().toEpochMilli()
-    val transactionRef = getRandomString(8)
-    transaction {
-        BankAccountTransactionEntity.new {
-            creditorIban = creditAccount.iban
-            creditorBic = creditAccount.bic
-            this.creditorName = getPersonNameFromCustomer(creditAccount.owner)
-            debtorIban = debitAccount.iban
-            debtorBic = debitAccount.bic
-            debtorName = getPersonNameFromCustomer(debitAccount.owner)
-            this.subject = subject
-            this.amount = amount
-            this.currency = demobank.currency
-            date = timeStamp
-            accountServicerReference = transactionRef
-            account = creditAccount
-            direction = "CRDT"
-            this.demobank = demobank
-            this.pmtInfId = pmtInfId
-        }
-        BankAccountTransactionEntity.new {
-            creditorIban = creditAccount.iban
-            creditorBic = creditAccount.bic
-            this.creditorName = getPersonNameFromCustomer(creditAccount.owner)
-            debtorIban = debitAccount.iban
-            debtorBic = debitAccount.bic
-            debtorName = getPersonNameFromCustomer(debitAccount.owner)
-            this.subject = subject
-            this.amount = amount
-            this.currency = demobank.currency
-            date = timeStamp
-            accountServicerReference = transactionRef
-            account = debitAccount
-            direction = "DBIT"
-            this.demobank = demobank
-            this.pmtInfId = pmtInfId
-        }
-    }
-    return transactionRef
-}
-
 fun getWithdrawalOperation(opId: String): TalerWithdrawalEntity {
     return transaction {
         TalerWithdrawalEntity.find {
-            TalerWithdrawalsTable.wopid eq java.util.UUID.fromString(opId)
+            TalerWithdrawalsTable.wopid eq UUID.fromString(opId)
         }.firstOrNull() ?: throw SandboxError(
             HttpStatusCode.NotFound, "Withdrawal operation $opId not found."
         )
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 6a26aea3..bf929de0 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -251,11 +251,8 @@ class Camt053Tick : CliktCommand(
                  * Resorting the closing (CLBD) balance of the last statement; 
will
                  * become the PRCD balance of the _new_ one.
                  */
-                val lastBalance = getLastBalance(accountIter)
-                val balanceClbd = balanceForAccount(
-                    history = newStatements[accountIter.label] ?: 
mutableListOf(),
-                    baseBalance = lastBalance
-                )
+                val lastBalance = getBalance(accountIter, withPending = false)
+                val balanceClbd = getBalance(accountIter, withPending = true)
                 val camtData = buildCamtString(
                     53,
                     accountIter.iban,
@@ -671,7 +668,7 @@ val sandboxApp: Application.() -> Unit = {
                 val bankAccount = getBankAccountFromLabel(label, demobank)
                 if (!allowOwnerOrAdmin(username, label))
                     throw unauthorized("'${username}' has no rights over 
'$label'")
-                val balance = balanceForAccount(bankAccount)
+                val balance = getBalance(bankAccount, withPending = true)
                 object {
                     val balance = "${bankAccount.demoBank.currency}:${balance}"
                     val iban = bankAccount.iban
@@ -1192,7 +1189,7 @@ val sandboxApp: Application.() -> Unit = {
                     val ret = TalerWithdrawalStatus(
                         selection_done = wo.selectionDone,
                         transfer_done = wo.confirmationDone,
-                        amount = "${demobank.currency}:${wo.amount}",
+                        amount = wo.amount,
                         suggested_exchange = demobank.suggestedExchangeBaseUrl,
                         aborted = wo.aborted,
                         confirm_transfer_url = captcha_page
@@ -1209,14 +1206,10 @@ val sandboxApp: Application.() -> Unit = {
                     val payto = parsePayto(req.paytoUri)
                     val amount: String? = payto.amount ?: req.amount
                     if (amount == null) throw badRequest("Amount is missing")
-                    val amountParsed = parseAmountAsString(amount)
                     /**
                      * The transaction block below lets the 'demoBank' field
                      * of 'bankAccount' be correctly accessed.  */
                     transaction {
-                        if ((amountParsed.second != null)
-                            && (bankAccount.demoBank.currency != 
amountParsed.second))
-                            throw badRequest("Currency 
'${amountParsed.second}' is wrong")
                         wireTransfer(
                             debitAccount = bankAccount,
                             creditAccount = getBankAccountFromIban(payto.iban),
@@ -1224,7 +1217,7 @@ val sandboxApp: Application.() -> Unit = {
                             subject = payto.message ?: throw badRequest(
                                 "'message' query parameter missing in Payto 
address"
                             ),
-                            amount = amountParsed.first
+                            amount = amount
                         )
                     }
                     call.respond(object {})
@@ -1233,13 +1226,13 @@ val sandboxApp: Application.() -> Unit = {
                 // Information about one withdrawal.
                 get("/accounts/{account_name}/withdrawals/{withdrawal_id}") {
                     val op = 
getWithdrawalOperation(call.getUriComponent("withdrawal_id"))
-                    val demobank = ensureDemobank(call)
+                    ensureDemobank(call)
                     if (!op.selectionDone && op.reservePub != null) throw 
internalServerError(
                         "Unselected withdrawal has a reserve public key",
                         LibeufinErrorCode.LIBEUFIN_EC_INCONSISTENT_STATE
                     )
                     call.respond(object {
-                        val amount = "${demobank.currency}:${op.amount}"
+                        val amount = op.amount
                         val aborted = op.aborted
                         val confirmation_done = op.confirmationDone
                         val selection_done = op.selectionDone
@@ -1270,12 +1263,25 @@ val sandboxApp: Application.() -> Unit = {
                     val req = call.receiveJson<WithdrawalRequest>()
                     // Check for currency consistency
                     val amount = parseAmount(req.amount)
-                    if (amount.currency != demobank.currency) throw badRequest(
-                        "Currency ${amount.currency} differs from Demobank's: 
${demobank.currency}"
-                    )
+                    if (amount.currency != demobank.currency)
+                        throw badRequest("Currency ${amount.currency} differs 
from Demobank's: ${demobank.currency}")
+                    /**
+                     * Check for debit threshold.  That's however also later 
checked
+                     * after the /confirm call.  Username == null case is 
handled above.
+                     */
+                    val pendingBalance = getBalance(username!!, withPending = 
true)
+                    if ((pendingBalance - amount.amount).abs() > 
BigDecimal.valueOf(demobank.usersDebtLimit.toLong())) {
+                        logger.info("User $username would surpass user debit " 
+
+                                "threshold of ${demobank.usersDebtLimit}.  
Rollback Taler withdrawal"
+                        )
+                        throw SandboxError(
+                            HttpStatusCode.Forbidden,
+                            "Insufficient funds."
+                        )
+                    }
                     val wo: TalerWithdrawalEntity = transaction {
                         TalerWithdrawalEntity.new {
-                        this.amount = amount.amount.toPlainString()
+                        this.amount = req.amount
                         walletBankAccount = maybeOwnedAccount
                         }
                     }
@@ -1336,7 +1342,6 @@ val sandboxApp: Application.() -> Unit = {
                             )
                         )
                         if (!wo.confirmationDone) {
-                            // Need the exchange bank account!
                             wireTransfer(
                                 debitAccount = wo.walletBankAccount,
                                 creditAccount = exchangeBankAccount,
@@ -1382,7 +1387,7 @@ val sandboxApp: Application.() -> Unit = {
                     ) throw forbidden(
                             "Customer '$username' cannot access bank account 
'$accountAccessed'"
                         )
-                    val balance = balanceForAccount(bankAccount)
+                    val balance = getBalance(bankAccount, withPending = true)
                     call.respond(object {
                         val balance = object {
                             val amount = 
"${demobank.currency}:${balance.abs(). toPlainString()}"
@@ -1478,7 +1483,7 @@ val sandboxApp: Application.() -> Unit = {
                                     BankAccountsTable.demoBank eq demobank.id
                             )
                         }.forEach {
-                            val balanceIter = balanceForAccount(it)
+                            val balanceIter = getBalance(it, withPending = 
true)
                             ret.publicAccounts.add(
                                 PublicAccountInfo(
                                     balance = 
"${demobank.currency}:$balanceIter",
@@ -1564,7 +1569,7 @@ val sandboxApp: Application.() -> Unit = {
                             bankAccount.bonus("${demobank.currency}:100")
                         bankAccount
                     }
-                    val balance = balanceForAccount(bankAccount)
+                    val balance = getBalance(bankAccount, withPending = true)
                     call.respond(object {
                         val balance = object {
                             val amount = "${demobank.currency}:$balance"
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
index 852e4b39..74c04bfe 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
@@ -2,57 +2,175 @@ package tech.libeufin.sandbox
 
 import io.ktor.http.*
 import org.jetbrains.exposed.sql.and
-import 
org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
-import 
org.jetbrains.exposed.sql.transactions.experimental.suspendedTransactionAsync
 import org.jetbrains.exposed.sql.transactions.transaction
-import org.slf4j.Logger
-import org.slf4j.LoggerFactory
 import tech.libeufin.util.*
 import java.math.BigDecimal
 
-// Mainly useful inside the Camt generator.
-fun balanceForAccount(
-    history: MutableList<RawPayment>,
-    baseBalance: BigDecimal
+/**
+ * The last balance is the one mentioned in the bank account's
+ * last statement.  If the bank account does not have any statement
+ * yet, then zero is returned.  When 'withPending' is true, it adds
+ * the pending transactions to it.
+ */
+fun getBalance(
+    bankAccount: BankAccountEntity,
+    withPending: Boolean = true
 ): BigDecimal {
-    var ret = baseBalance
-    history.forEach direction@ {
-        if (it.direction == "CRDT") {
-            val amount = parseDecimal(it.amount)
-            ret += amount
-            return@direction
+    val lastStatement = transaction {
+        BankAccountStatementEntity.find {
+            BankAccountStatementsTable.bankAccount eq bankAccount.id
+        }.lastOrNull()
+    }
+    var lastBalance = if (lastStatement == null) {
+        BigDecimal.ZERO
+    } else { BigDecimal(lastStatement.balanceClbd) }
+    if (!withPending) return lastBalance
+    /**
+     * Caller asks to include the pending transactions in the
+     * balance.  The block below gets the transactions happened
+     * later than the last statement and adds them to the balance
+     * that was calculated so far.
+     */
+    transaction {
+        val pendingTransactions = BankAccountTransactionEntity.find {
+            BankAccountTransactionsTable.account eq bankAccount.id and (
+                    
BankAccountTransactionsTable.date.greater(lastStatement?.creationTime ?: 0L))
         }
-        if (it.direction == "DBIT") {
-            val amount = parseDecimal(it.amount)
-            ret -= amount
-            return@direction
+        pendingTransactions.forEach { tx ->
+            when (tx.direction) {
+                "DBIT" -> lastBalance -= parseDecimal(tx.amount)
+                "CRDT" -> lastBalance += parseDecimal(tx.amount)
+                else -> {
+                    logger.error("Transaction ${tx.id} is neither debit nor 
credit.")
+                    throw SandboxError(
+                        HttpStatusCode.InternalServerError,
+                        "Error in transactions state."
+                    )
+                }
+            }
         }
-        throw SandboxError(
-            HttpStatusCode.InternalServerError,
-            "A payment direction was found neither CRDT nor DBIT",
-            LibeufinErrorCode.LIBEUFIN_EC_INVALID_STATE
+    }
+    return lastBalance
+}
+
+// Wrapper offering to get bank accounts from a string.
+fun getBalance(accountLabel: String, withPending: Boolean = false): BigDecimal 
{
+    val account = transaction {
+        BankAccountEntity.find { BankAccountsTable.label.eq(accountLabel) 
}.firstOrNull()
+    }
+    if (account == null) throw notFound("Bank account $accountLabel not found")
+    return getBalance(account, withPending)
+}
+
+fun wireTransfer(
+    debitAccount: String,
+    creditAccount: String,
+    demobank: String,
+    subject: String,
+    amount: String, // $currency:x.y
+    pmtInfId: String? = null
+): String {
+    val args: Triple<BankAccountEntity, BankAccountEntity, 
DemobankConfigEntity> = transaction {
+        val debitAccountDb = BankAccountEntity.find {
+            BankAccountsTable.label eq debitAccount
+        }.firstOrNull() ?: throw SandboxError(
+            HttpStatusCode.NotFound,
+            "Debit account '$debitAccount' not found"
+        )
+        val creditAccountDb = BankAccountEntity.find {
+            BankAccountsTable.label eq creditAccount
+        }.firstOrNull() ?: throw SandboxError(
+            HttpStatusCode.NotFound,
+            "Credit account '$creditAccount' not found"
+        )
+        val demoBank = DemobankConfigEntity.find {
+            DemobankConfigsTable.name eq demobank
+        }.firstOrNull() ?: throw SandboxError(
+            HttpStatusCode.NotFound,
+            "Demobank '$demobank' not found"
         )
+
+        Triple(debitAccountDb, creditAccountDb, demoBank)
     }
-    return ret
+
+    return wireTransfer(
+        debitAccount = args.first,
+        creditAccount = args.second,
+        demobank = args.third,
+        subject = subject,
+        amount = amount,
+        pmtInfId
+    )
 }
+/**
+ * Book a CRDT and a DBIT transaction and return the unique reference thereof.
+ *
+ * At the moment there is redundancy because all the creditor / debtor details
+ * are contained (directly or indirectly) already in the BankAccount 
parameters.
+ *
+ * This is kept both not to break the existing tests and to allow future 
versions
+ * where one party of the transaction is not a customer of the running Sandbox.
+ */
 
-fun balanceForAccount(bankAccount: BankAccountEntity): BigDecimal {
-    var balance = BigDecimal.ZERO
+fun wireTransfer(
+    debitAccount: BankAccountEntity,
+    creditAccount: BankAccountEntity,
+    demobank: DemobankConfigEntity,
+    subject: String,
+    amount: String, // $currency:$value
+    pmtInfId: String? = null
+): String {
+    val checkAmount = parseAmount(amount)
+    if (checkAmount.amount == BigDecimal.ZERO)
+        throw badRequest("Wire transfers of zero not possible.")
+    if (checkAmount.currency != demobank.currency)
+        throw badRequest("Won't wire transfer with currency: 
${checkAmount.currency}")
+    // Check funds are sufficient.
+    val pendingBalance = getBalance(debitAccount, withPending = true)
+    val maxDebt = if (debitAccount.label == "bank") {
+        demobank.bankDebtLimit
+    } else demobank.usersDebtLimit
+    if ((pendingBalance - checkAmount.amount).abs() > 
BigDecimal.valueOf(maxDebt.toLong())) {
+        logger.info("Account ${debitAccount.label} would surpass debit 
threshold of $maxDebt.  Rollback wire transfer")
+        throw SandboxError(HttpStatusCode.PreconditionFailed, "Insufficient 
funds")
+    }
+    val timeStamp = getUTCnow().toInstant().toEpochMilli()
+    val transactionRef = getRandomString(8)
     transaction {
-        BankAccountTransactionEntity.find {
-            BankAccountTransactionsTable.direction eq "CRDT" and (
-                    BankAccountTransactionsTable.account eq bankAccount.id)
-        }.forEach {
-            val amount = parseDecimal(it.amount)
-            balance += amount
+        BankAccountTransactionEntity.new {
+            creditorIban = creditAccount.iban
+            creditorBic = creditAccount.bic
+            this.creditorName = getPersonNameFromCustomer(creditAccount.owner)
+            debtorIban = debitAccount.iban
+            debtorBic = debitAccount.bic
+            debtorName = getPersonNameFromCustomer(debitAccount.owner)
+            this.subject = subject
+            this.amount = checkAmount.amount.toPlainString()
+            this.currency = demobank.currency
+            date = timeStamp
+            accountServicerReference = transactionRef
+            account = creditAccount
+            direction = "CRDT"
+            this.demobank = demobank
+            this.pmtInfId = pmtInfId
         }
-        BankAccountTransactionEntity.find {
-            BankAccountTransactionsTable.direction eq "DBIT" and (
-                    BankAccountTransactionsTable.account eq bankAccount.id)
-        }.forEach {
-            val amount = parseDecimal(it.amount)
-            balance -= amount
+        BankAccountTransactionEntity.new {
+            creditorIban = creditAccount.iban
+            creditorBic = creditAccount.bic
+            this.creditorName = getPersonNameFromCustomer(creditAccount.owner)
+            debtorIban = debitAccount.iban
+            debtorBic = debitAccount.bic
+            debtorName = getPersonNameFromCustomer(debitAccount.owner)
+            this.subject = subject
+            this.amount = checkAmount.amount.toPlainString()
+            this.currency = demobank.currency
+            date = timeStamp
+            accountServicerReference = transactionRef
+            account = debitAccount
+            direction = "DBIT"
+            this.demobank = demobank
+            this.pmtInfId = pmtInfId
         }
     }
-    return balance
+    return transactionRef
 }
\ No newline at end of file
diff --git a/sandbox/src/test/kotlin/BalanceTest.kt 
b/sandbox/src/test/kotlin/BalanceTest.kt
index f4f99584..48497e98 100644
--- a/sandbox/src/test/kotlin/BalanceTest.kt
+++ b/sandbox/src/test/kotlin/BalanceTest.kt
@@ -16,7 +16,8 @@ class BalanceTest {
                 SchemaUtils.create(
                     BankAccountsTable,
                     BankAccountTransactionsTable,
-                    BankAccountFreshTransactionsTable
+                    BankAccountFreshTransactionsTable,
+                    BankAccountStatementsTable
                 )
                 val demobank = DemobankConfigEntity.new {
                     currency = "EUR"
@@ -84,7 +85,7 @@ class BalanceTest {
                     accountServicerReference = 
"test-account-servicer-reference"
                     this.demobank = demobank
                 }
-                assert(BigDecimal.ONE == balanceForAccount(one))
+                assert(BigDecimal.ONE == getBalance(one, withPending = true))
             }
         }
     }

-- 
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]