--
-- This file is part of TALER
-- Copyright (C) 2026 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-0015', NULL, NULL);

SET search_path TO libeufin_bank;

-- Allow withdrawal not linked to a bank account
-- Store the exchange account ID instead of the payto
-- Support non reserve withdrawals
ALTER TABLE taler_withdrawal_operations ALTER COLUMN wallet_bank_account DROP NOT NULL,
                                        ADD COLUMN exchange_bank_account INT8 REFERENCES bank_accounts(bank_account_id) ON DELETE SET NULL,
                                        ADD COLUMN type taler_incoming_type NOT NULL DEFAULT 'reserve',
                                        DROP CONSTRAINT taler_withdrawal_operations_reserve_pub_key;
UPDATE taler_withdrawal_operations SET exchange_bank_account=(SELECT bank_account_id FROM bank_accounts WHERE internal_payto=selected_exchange_payto);
ALTER TABLE taler_withdrawal_operations DROP COLUMN selected_exchange_payto;
CREATE UNIQUE INDEX taler_withdrawal_operations_unique_reserve_pub 
    ON taler_withdrawal_operations (reserve_pub) WHERE type = 'reserve';

-- Add outgoing transactions metadata field
ALTER TABLE transfer_operations ADD COLUMN metadata TEXT;

-- Replace unused wad type with new mapping type
ALTER TYPE taler_incoming_type RENAME VALUE 'wad' TO 'map';

ALTER TABLE taler_exchange_incoming
    ADD COLUMN authorization_pub BYTEA CHECK (LENGTH(authorization_pub)=32),
    ADD COLUMN authorization_sig BYTEA CHECK (LENGTH(authorization_sig)=64);

CREATE TABLE prepared_transfers (
    type taler_incoming_type NOT NULL,
    account_pub BYTEA NOT NULL CHECK (LENGTH(account_pub)=32),
    authorization_pub BYTEA UNIQUE NOT NULL CHECK (LENGTH(authorization_pub)=32),
    authorization_sig BYTEA NOT NULL CHECK (LENGTH(authorization_sig)=64),
    recurrent BOOLEAN NOT NULL,
    withdrawal_id INT8 UNIQUE REFERENCES taler_withdrawal_operations(withdrawal_id),
    registered_at INT8 NOT NULL,
    bank_transaction_id INT8 UNIQUE REFERENCES bank_account_transactions(bank_transaction_id) ON DELETE CASCADE
);
CREATE UNIQUE INDEX prepared_transfers_unique_reserve_pub 
    ON prepared_transfers (account_pub) WHERE type = 'reserve';
CREATE INDEX prepared_transfers_timestamp
    ON prepared_transfers (registered_at);

CREATE TABLE pending_recurrent_incoming_transactions(
    bank_transaction_id INT8 NOT NULL UNIQUE REFERENCES bank_account_transactions(bank_transaction_id) ON DELETE CASCADE,
    debtor_account_id INT8 NOT NULL REFERENCES bank_accounts(bank_account_id) ON DELETE CASCADE,
    authorization_pub BYTEA NOT NULL REFERENCES prepared_transfers(authorization_pub)
);
CREATE INDEX pending_recurrent_incoming_transactions_auth_pub
    ON pending_recurrent_incoming_transactions (authorization_pub);

COMMIT;
