libeufin

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

commit c117fc2e208adc9a22a85c196a61c6d0a0a39ade
parent 665b8f15eae8d612264c239572641d3ccae1a38f
Author: Antoine A <>
Date:   Mon,  6 Jan 2025 10:31:05 +0100

bank: support no_amount_to_wallet withdrawal field

Diffstat:
Mbank/src/main/kotlin/tech/libeufin/bank/Constants.kt | 6+++---
Mbank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt | 7+++++--
Mbank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt | 3++-
Mbank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt | 26++++++++++++++++----------
Mbank/src/test/kotlin/GcTest.kt | 6+++---
Adatabase-versioning/libeufin-bank-0012.sql | 24++++++++++++++++++++++++
Mdatabase-versioning/libeufin-bank-procedures.sql | 34+++++++++++++++++++++++++++++++---
Mtestbench/src/test/kotlin/MigrationTest.kt | 5++++-
8 files changed, 88 insertions(+), 23 deletions(-)

diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt b/bank/src/main/kotlin/tech/libeufin/bank/Constants.kt @@ -1,6 +1,6 @@ /* * This file is part of LibEuFin. - * Copyright (C) 2024 Taler Systems S.A. + * Copyright (C) 2024-2025 Taler Systems S.A. * LibEuFin is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -39,6 +39,6 @@ const val MAX_TOKEN_CREATION_ATTEMPTS: Int = 5 const val MAX_ACTIVE_CHALLENGES: Int = 5 // API version -const val COREBANK_API_VERSION: String = "7:0:4" +const val COREBANK_API_VERSION: String = "8:0:5" const val CONVERSION_API_VERSION: String = "0:1:0" -const val INTEGRATION_API_VERSION: String = "4:0:4" +const val INTEGRATION_API_VERSION: String = "5:0:5" diff --git a/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt b/bank/src/main/kotlin/tech/libeufin/bank/TalerMessage.kt @@ -1,6 +1,6 @@ /* * This file is part of LibEuFin. - * Copyright (C) 2024 Taler Systems S.A. + * Copyright (C) 2024-2025 Taler Systems S.A. * LibEuFin is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -469,7 +469,8 @@ data class BankAccountTransactionsResponse( @Serializable data class BankAccountCreateWithdrawalRequest( val amount: TalerAmount? = null, - val suggested_amount: TalerAmount? = null + val suggested_amount: TalerAmount? = null, + val no_amount_to_wallet: Boolean = false ) // Taler withdrawal response. @@ -484,6 +485,7 @@ data class WithdrawalPublicInfo ( val status: WithdrawalStatus, val amount: TalerAmount? = null, val suggested_amount: TalerAmount? = null, + val no_amount_to_wallet: Boolean, val username: String, val selected_reserve_pub: EddsaPublicKey? = null, val selected_exchange_account: String? = null, @@ -514,6 +516,7 @@ data class BankWithdrawalOperationStatus( val wire_types: List<String>, val selected_reserve_pub: EddsaPublicKey? = null, val selected_exchange_account: String? = null, + val no_amount_to_wallet: Boolean = false, val currency: String? = null, // TODO deprecated remove in the next breaking release val aborted: Boolean, diff --git a/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt b/bank/src/main/kotlin/tech/libeufin/bank/api/CoreBankApi.kt @@ -1,6 +1,6 @@ /* * This file is part of LibEuFin. - * Copyright (C) 2023-2024 Taler Systems S.A. + * Copyright (C) 2023-2025 Taler Systems S.A. * LibEuFin is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -530,6 +530,7 @@ private fun Routing.coreBankWithdrawalApi(db: Database, cfg: BankConfig) { opId, req.amount, req.suggested_amount, + req.no_amount_to_wallet, Instant.now(), cfg.wireTransferFees, cfg.minAmount, diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/WithdrawalDAO.kt @@ -1,6 +1,6 @@ /* * This file is part of LibEuFin. - * Copyright (C) 2023-2024 Taler Systems S.A. + * Copyright (C) 2023-2025 Taler Systems S.A. * LibEuFin is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -49,6 +49,7 @@ class WithdrawalDAO(private val db: Database) { uuid: UUID, amount: TalerAmount?, suggested_amount: TalerAmount?, + no_amount_to_wallet: Boolean, timestamp: Instant, wireTransferFees: TalerAmount, minAmount: TalerAmount, @@ -64,7 +65,7 @@ class WithdrawalDAO(private val db: Database) { ?,?, ${if (amount != null) "(?,?)::taler_amount" else "NULL"}, ${if (suggested_amount != null) "(?,?)::taler_amount" else "NULL"}, - ?, (?, ?)::taler_amount, (?, ?)::taler_amount, (?, ?)::taler_amount + ?, ?, (?, ?)::taler_amount, (?, ?)::taler_amount, (?, ?)::taler_amount ); """ ) { @@ -81,13 +82,14 @@ class WithdrawalDAO(private val db: Database) { setInt(id+1, suggested_amount.frac) id += 2 } - setLong(id, timestamp.micros()) - setLong(id+1, wireTransferFees.value) - setInt(id+2, wireTransferFees.frac) - setLong(id+3, minAmount.value) - setInt(id+4, minAmount.frac) - setLong(id+5, maxAmount.value) - setInt(id+6, maxAmount.frac) + setBoolean(id, no_amount_to_wallet) + setLong(id+1, timestamp.micros()) + setLong(id+2, wireTransferFees.value) + setInt(id+3, wireTransferFees.frac) + setLong(id+4, minAmount.value) + setInt(id+5, minAmount.frac) + setLong(id+6, maxAmount.value) + setInt(id+7, maxAmount.frac) one { when { it.getBoolean("out_account_not_found") -> WithdrawalCreationResult.UnknownAccount @@ -334,6 +336,7 @@ class WithdrawalDAO(private val db: Database) { ,reserve_pub ,selected_exchange_payto ,username + ,no_amount_to_wallet FROM taler_withdrawal_operations JOIN bank_accounts ON wallet_bank_account=bank_account_id JOIN customers ON customer_id=owning_customer_id @@ -348,7 +351,8 @@ class WithdrawalDAO(private val db: Database) { suggested_amount = it.getOptAmount("suggested_amount", db.bankCurrency), username = it.getString("username"), selected_exchange_account = it.getString("selected_exchange_payto"), - selected_reserve_pub = it.getBytes("reserve_pub")?.run(::EddsaPublicKey) + selected_reserve_pub = it.getBytes("reserve_pub")?.run(::EddsaPublicKey), + no_amount_to_wallet = it.getBoolean("no_amount_to_wallet") ) } } @@ -384,6 +388,7 @@ class WithdrawalDAO(private val db: Database) { ,selected_exchange_payto ,(max_amount).val as max_amount_val ,(max_amount).frac as max_amount_frac + ,no_amount_to_wallet FROM taler_withdrawal_operations JOIN bank_accounts ON (wallet_bank_account=bank_account_id) JOIN customers ON (owning_customer_id=customer_id) @@ -407,6 +412,7 @@ class WithdrawalDAO(private val db: Database) { confirm_transfer_url = null, suggested_exchange = null, selected_exchange_account = it.getString("selected_exchange_payto"), + no_amount_to_wallet = it.getBoolean("no_amount_to_wallet"), selected_reserve_pub = it.getBytes("reserve_pub")?.run(::EddsaPublicKey), wire_types = listOf( when (wire) { diff --git a/bank/src/test/kotlin/GcTest.kt b/bank/src/test/kotlin/GcTest.kt @@ -1,6 +1,6 @@ /* * This file is part of LibEuFin. - * Copyright (C) 2024 Taler Systems S.A. + * Copyright (C) 2024-2025 Taler Systems S.A. * LibEuFin is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -104,7 +104,7 @@ class GcTest { for (time in times) { val uuid = UUID.randomUUID() assertEquals( - db.withdrawal.create(account, uuid, from, null, time, ZERO, ZERO, MAX), + db.withdrawal.create(account, uuid, from, null, false, time, ZERO, ZERO, MAX), WithdrawalCreationResult.Success ) assertIs<WithdrawalSelectionResult.Success>( @@ -123,7 +123,7 @@ class GcTest { } for (time in listOf(now, abort, clean, delete)) { assertEquals( - db.withdrawal.create(account, UUID.randomUUID(), from, null, time, ZERO, ZERO, MAX), + db.withdrawal.create(account, UUID.randomUUID(), from, null, false, time, ZERO, ZERO, MAX), WithdrawalCreationResult.Success ) } diff --git a/database-versioning/libeufin-bank-0012.sql b/database-versioning/libeufin-bank-0012.sql @@ -0,0 +1,24 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2025 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + +BEGIN; + +SELECT _v.register_patch('libeufin-bank-0012', NULL, NULL); +SET search_path TO libeufin_bank; + +-- Add no_amount_to_wallet for withdrawal +ALTER TABLE taler_withdrawal_operations ADD COLUMN no_amount_to_wallet BOOLEAN DEFAULT false; + +COMMIT; diff --git a/database-versioning/libeufin-bank-procedures.sql b/database-versioning/libeufin-bank-procedures.sql @@ -1,3 +1,18 @@ +-- +-- This file is part of TALER +-- Copyright (C) 2023-2025 Taler Systems SA +-- +-- TALER is free software; you can redistribute it and/or modify it under the +-- terms of the GNU General Public License as published by the Free Software +-- Foundation; either version 3, or (at your option) any later version. +-- +-- TALER is distributed in the hope that it will be useful, but WITHOUT ANY +-- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +-- A PARTICULAR PURPOSE. See the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License along with +-- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + BEGIN; SET search_path TO libeufin_bank; @@ -959,6 +974,7 @@ CREATE FUNCTION create_taler_withdrawal( IN in_withdrawal_uuid UUID, IN in_amount taler_amount, IN in_suggested_amount taler_amount, + IN in_no_amount_to_wallet BOOLEAN, IN in_timestamp INT8, IN in_wire_transfer_fees taler_amount, IN in_min_amount taler_amount, @@ -1000,9 +1016,21 @@ IF in_amount IS NOT NULL OR in_suggested_amount IS NOT NULL THEN END IF; -- Create withdrawal operation -INSERT INTO taler_withdrawal_operations - (withdrawal_uuid, wallet_bank_account, amount, suggested_amount, creation_date) - VALUES (in_withdrawal_uuid, account_id, in_amount, in_suggested_amount, in_timestamp); +INSERT INTO taler_withdrawal_operations ( + withdrawal_uuid, + wallet_bank_account, + amount, + suggested_amount, + no_amount_to_wallet, + creation_date +) VALUES ( + in_withdrawal_uuid, + account_id, + in_amount, + in_suggested_amount, + in_no_amount_to_wallet, + in_timestamp +); END $$; COMMENT ON FUNCTION create_taler_withdrawal IS 'Create a new withdrawal operation'; diff --git a/testbench/src/test/kotlin/MigrationTest.kt b/testbench/src/test/kotlin/MigrationTest.kt @@ -1,6 +1,6 @@ /* * This file is part of LibEuFin. - * Copyright (C) 2024 Taler Systems S.A. + * Copyright (C) 2025 Taler Systems S.A. * LibEuFin is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -83,6 +83,9 @@ class MigrationTest { // libeufin-bank-0011 conn.execSQLUpdate(Path("../database-versioning/libeufin-bank-0011.sql").readText()) + // libeufin-bank-0012 + conn.execSQLUpdate(Path("../database-versioning/libeufin-bank-0012.sql").readText()) + // libeufin-nexus-0001 conn.execSQLUpdate(Path("../database-versioning/libeufin-nexus-0001.sql").readText()) conn.execSQLUpdate("""