libeufin

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

commit d527df40d0553bbe6c20bfac0754e8a0253d02d4
parent 4c44480327c5ffc7cb925f2264dd401769d48ddb
Author: MS <ms@taler.net>
Date:   Thu, 27 May 2021 15:34:20 +0200

Calculating balances in the Sandbox.

At this point, the Sandbox goes through the whole
history of one account (= one IBAN) and calculates
the balance for it.

Later, a mechanism to calculate the balance only
based on a subset of such transactions should be
provided.

Diffstat:
Msandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 2+-
Msandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt | 24+++++++++++++++++++++++-
Asandbox/src/test/kotlin/BalanceTest.kt | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -307,7 +307,7 @@ fun buildCamtString(type: Int, subscriberIban: String, history: List<RawPayment> } element("Amt") { attribute("Ccy", "EUR") - text(Amount(0).toPlainString()) + text(balanceForAccount(subscriberIban).toString()) } element("CdtDbtInd") { // a temporary value to get the camt to validate. diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt @@ -5,16 +5,38 @@ import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.transactions.transaction import org.slf4j.Logger import org.slf4j.LoggerFactory +import tech.libeufin.sandbox.BankAccountTransactionsTable.amount import tech.libeufin.util.RawPayment import tech.libeufin.util.importDateFromMillis import tech.libeufin.util.toDashedDate +import java.math.BigInteger private val logger: Logger = LoggerFactory.getLogger("tech.libeufin.sandbox") +fun balanceForAccount(iban: String): BigInteger { + logger.debug("Calculating balance for account: ${iban}") + var balance = BigInteger.ZERO + transaction { + BankAccountTransactionsTable.select { + BankAccountTransactionsTable.creditorIban eq iban + }.forEach { + val amount = BigInteger(it[amount]) + balance += amount + } + BankAccountTransactionsTable.select { + BankAccountTransactionsTable.debtorIban eq iban + }.forEach { + val amount = BigInteger(it[amount]) + balance -= amount + } + } + return balance +} + fun historyForAccount(iban: String): List<RawPayment> { val history = mutableListOf<RawPayment>() + logger.debug("Querying transactions involving: ${iban}") transaction { - logger.debug("Querying transactions involving: ${iban}") BankAccountTransactionsTable.select { BankAccountTransactionsTable.creditorIban eq iban or (BankAccountTransactionsTable.debtorIban eq iban) diff --git a/sandbox/src/test/kotlin/BalanceTest.kt b/sandbox/src/test/kotlin/BalanceTest.kt @@ -0,0 +1,72 @@ +import org.jetbrains.exposed.dao.id.EntityID +import org.jetbrains.exposed.sql.SchemaUtils +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.transactions.transaction +import org.junit.Test +import tech.libeufin.sandbox.BankAccountTransactionsTable +import tech.libeufin.sandbox.BankAccountsTable +import tech.libeufin.sandbox.balanceForAccount +import tech.libeufin.util.millis +import java.math.BigInteger +import java.time.LocalDateTime + +class BalanceTest { + + @Test + fun balanceTest() { + withTestDatabase { + transaction { + SchemaUtils.create(BankAccountTransactionsTable) + BankAccountTransactionsTable.insert { + it[account] = EntityID(0, BankAccountsTable) + it[creditorIban] = "earns" + it[creditorBic] = "BIC" + it[creditorName] = "Creditor Name" + it[debtorIban] = "spends" + it[debtorBic] = "BIC" + it[debtorName] = "Debitor Name" + it[subject] = "deal" + it[amount] = "1" + it[date] = LocalDateTime.now().millis() + it[currency] = "EUR" + it[pmtInfId] = "0" + it[direction] = "DBIT" + it[accountServicerReference] = "test-account-servicer-reference" + } + BankAccountTransactionsTable.insert { + it[account] = EntityID(0, BankAccountsTable) + it[creditorIban] = "earns" + it[creditorBic] = "BIC" + it[creditorName] = "Creditor Name" + it[debtorIban] = "spends" + it[debtorBic] = "BIC" + it[debtorName] = "Debitor Name" + it[subject] = "deal" + it[amount] = "1" + it[date] = LocalDateTime.now().millis() + it[currency] = "EUR" + it[pmtInfId] = "0" + it[direction] = "DBIT" + it[accountServicerReference] = "test-account-servicer-reference" + } + BankAccountTransactionsTable.insert { + it[account] = EntityID(0, BankAccountsTable) + it[creditorIban] = "other" + it[creditorBic] = "BIC" + it[creditorName] = "Creditor Name" + it[debtorIban] = "earns" + it[debtorBic] = "BIC" + it[debtorName] = "Debitor Name" + it[subject] = "deal" + it[amount] = "1" + it[date] = LocalDateTime.now().millis() + it[currency] = "EUR" + it[pmtInfId] = "0" + it[direction] = "DBIT" + it[accountServicerReference] = "test-account-servicer-reference" + } + assert(BigInteger.ONE == balanceForAccount("earns")) + } + } + } +} +\ No newline at end of file