diff options
author | MS <ms@taler.net> | 2023-09-02 11:00:52 +0200 |
---|---|---|
committer | MS <ms@taler.net> | 2023-09-02 11:00:52 +0200 |
commit | d6f75f52ed1c9a5508effeef669c513509e88536 (patch) | |
tree | 9efea5699b8b1a29dc0b916173c7c330dc41fc85 /sandbox/src/main/kotlin/tech/libeufin | |
parent | 6da1ee06fe2bac9c601f3d33df40de6f139e8a34 (diff) | |
download | libeufin-d6f75f52ed1c9a5508effeef669c513509e88536.tar.gz libeufin-d6f75f52ed1c9a5508effeef669c513509e88536.tar.bz2 libeufin-d6f75f52ed1c9a5508effeef669c513509e88536.zip |
bank DB: conditional cash-out deletion.
Diffstat (limited to 'sandbox/src/main/kotlin/tech/libeufin')
-rw-r--r-- | sandbox/src/main/kotlin/tech/libeufin/sandbox/Database.kt | 123 |
1 files changed, 119 insertions, 4 deletions
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Database.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Database.kt index ec6a3196..243efe2c 100644 --- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Database.kt +++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Database.kt @@ -330,9 +330,18 @@ class Database(private val dbConfig: String) { val rs = stmt.executeQuery() rs.use { if (!rs.next()) throw internalServerError("Bank transaction didn't properly return") - if (rs.getBoolean("out_nx_debtor")) return BankTransactionResult.NO_DEBTOR - if (rs.getBoolean("out_nx_creditor")) return BankTransactionResult.NO_CREDITOR - if (rs.getBoolean("out_balance_insufficient")) return BankTransactionResult.CONFLICT + if (rs.getBoolean("out_nx_debtor")) { + logger.error("No debtor account found") + return BankTransactionResult.NO_DEBTOR + } + if (rs.getBoolean("out_nx_creditor")) { + logger.error("No creditor account found") + return BankTransactionResult.NO_CREDITOR + } + if (rs.getBoolean("out_balance_insufficient")) { + logger.error("Balance insufficient") + return BankTransactionResult.CONFLICT + } return BankTransactionResult.SUCCESS } } @@ -509,7 +518,7 @@ class Database(private val dbConfig: String) { ,bank_account ,cashout_address ,cashout_currency - ) + ) VALUES ( ? ,(?,?)::taler_amount @@ -548,6 +557,112 @@ class Database(private val dbConfig: String) { return myExecute(stmt) } + fun cashoutConfirm( + opUuid: UUID, + tanConfirmationTimestamp: Long, + bankTransaction: Long // regional payment backing the operation + ): Boolean { + reconnect() + val stmt = prepare(""" + UPDATE cashout_operations + SET tan_confirmation_time = ?, local_transaction = ? + WHERE cashout_uuid=?; + """) + stmt.setLong(1, tanConfirmationTimestamp) + stmt.setLong(2, bankTransaction) + stmt.setObject(3, opUuid) + return myExecute(stmt) + } + // used by /abort + enum class CashoutDeleteResult { + SUCCESS, + CONFLICT_ALREADY_CONFIRMED + } + fun cashoutDelete(opUuid: UUID): CashoutDeleteResult { + val stmt = prepare(""" + SELECT out_already_confirmed + FROM cashout_delete(?) + """) + stmt.setObject(1, opUuid) + stmt.executeQuery().use { + if (!it.next()) { + throw internalServerError("Cashout deletion gave no result") + } + if (it.getBoolean("out_already_confirmed")) return CashoutDeleteResult.CONFLICT_ALREADY_CONFIRMED + return CashoutDeleteResult.SUCCESS + } + } + fun cashoutGetFromUuid(opUuid: UUID): Cashout? { + val stmt = prepare(""" + SELECT + (amount_debit).val as amount_debit_val + ,(amount_debit).frac as amount_debit_frac + ,(amount_credit).val as amount_credit_val + ,(amount_credit).frac as amount_credit_frac + ,buy_at_ratio + ,(buy_in_fee).val as buy_in_fee_val + ,(buy_in_fee).frac as buy_in_fee_frac + ,sell_at_ratio + ,(sell_out_fee).val as sell_out_fee_val + ,(sell_out_fee).frac as sell_out_fee_frac + ,subject + ,creation_time + ,tan_channel + ,tan_code + ,bank_account + ,cashout_address + ,cashout_currency + ,tan_confirmation_time + ,local_transaction + FROM cashout_operations + WHERE cashout_uuid=?; + """) + stmt.setObject(1, opUuid) + stmt.executeQuery().use { + if (!it.next()) return null + return Cashout( + amountDebit = TalerAmount( + value = it.getLong("amount_debit_val"), + frac = it.getInt("amount_debit_frac") + ), + amountCredit = TalerAmount( + value = it.getLong("amount_credit_val"), + frac = it.getInt("amount_credit_frac") + ), + bankAccount = it.getLong("bank_account"), + buyAtRatio = it.getInt("buy_at_ratio"), + buyInFee = TalerAmount( + value = it.getLong("buy_in_fee_val"), + frac = it.getInt("buy_in_fee_frac") + ), + cashoutAddress = it.getString("cashout_address"), + cashoutCurrency = it.getString("cashout_currency"), + cashoutUuid = opUuid, + creationTime = it.getLong("creation_time"), + sellAtRatio = it.getInt("sell_at_ratio"), + sellOutFee = TalerAmount( + value = it.getLong("sell_out_fee_val"), + frac = it.getInt("sell_out_fee_frac") + ), + subject = it.getString("subject"), + tanChannel = it.getString("tan_channel").run { + when(this) { + "sms" -> TanChannel.sms + "email" -> TanChannel.email + "file" -> TanChannel.file + else -> throw internalServerError("TAN channel $this unsupported") + } + }, + tanCode = it.getString("tan_code"), + localTransaction = it.getLong("local_transaction"), + tanConfirmationTime = it.getLong("tan_confirmation_time").run { + if (this == 0L) return@run null + return@run this + } + ) + } + } + // NOTE: EBICS not needed for BFH and NB. } |