commit f23911edb73eddbbedca29d03196c95a10e419ed
parent 7d2c532d9f67b20e76459ed2d80d03d59c810199
Author: MS <ms@taler.net>
Date: Sat, 7 Jan 2023 13:40:55 +0100
Introduce debit check helper.
Diffstat:
1 file changed, 30 insertions(+), 21 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
@@ -7,6 +7,32 @@ import tech.libeufin.util.*
import java.math.BigDecimal
/**
+ * Check whether the given bank account would surpass the
+ * debit threshold, in case the potential amount gets transferred.
+ * Returns true when the debit WOULD be surpassed. */
+fun maybeDebit(
+ accountLabel: String,
+ requestedAmount: BigDecimal,
+ demobankName: String = "default"
+): Boolean {
+ val demobank = getDemobank(demobankName) ?: throw notFound(
+ "Demobank '${demobankName}' not found when trying to check the debit threshold" +
+ " for user $accountLabel"
+ )
+ val balance = getBalance(accountLabel, withPending = true)
+ val maxDebt = if (accountLabel == "admin") {
+ demobank.bankDebtLimit
+ } else demobank.usersDebtLimit
+ val balanceCheck = balance - requestedAmount
+ if (balanceCheck < BigDecimal.ZERO && balanceCheck.abs() > BigDecimal.valueOf(maxDebt.toLong())) {
+ logger.warn("User '$accountLabel' would surpass the debit" +
+ " threshold of $maxDebt, given the requested amount of ${requestedAmount.toPlainString()}")
+ return true
+ }
+ return false
+}
+
+/**
* 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
@@ -54,7 +80,7 @@ fun getBalance(
}
// Wrapper offering to get bank accounts from a string.
-fun getBalance(accountLabel: String, withPending: Boolean = false): BigDecimal {
+fun getBalance(accountLabel: String, withPending: Boolean = true): BigDecimal {
val defaultDemobank = getDefaultDemobank()
val account = getBankAccountFromLabel(accountLabel, defaultDemobank)
return getBalance(account, withPending)
@@ -90,16 +116,8 @@ fun wireTransfer(
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.
- */
+// Book a CRDT and a DBIT transaction and return the unique reference thereof.
fun wireTransfer(
debitAccount: BankAccountEntity,
creditAccount: BankAccountEntity,
@@ -118,17 +136,8 @@ fun wireTransfer(
" Only ${demobank.currency} allowed."
)
// Check funds are sufficient.
- /**
- * Using 'pending' balance because Libeufin never books. The
- * reason is that booking is not Taler-relevant.
- */
- val pendingBalance = getBalance(debitAccount, withPending = true)
- val maxDebt = if (debitAccount.label == "admin") {
- demobank.bankDebtLimit
- } else demobank.usersDebtLimit
- val balanceCheck = pendingBalance - amountAsNumber
- if (balanceCheck < BigDecimal.ZERO && balanceCheck.abs() > BigDecimal.valueOf(maxDebt.toLong())) {
- logger.info("Account ${debitAccount.label} would surpass debit threshold of $maxDebt. Rollback wire transfer")
+ if (maybeDebit(debitAccount.label, amountAsNumber)) {
+ logger.error("Account ${debitAccount.label} would surpass debit threshold. Rollback wire transfer")
throw SandboxError(HttpStatusCode.PreconditionFailed, "Insufficient funds")
}
val timeStamp = getUTCnow().toInstant().toEpochMilli()