pg_increment_money_pots.sql (3182B)
1 -- 2 -- This file is part of TALER 3 -- Copyright (C) 2025 Taler Systems SA 4 -- 5 -- TALER is free software; you can redistribute it and/or modify it under the 6 -- terms of the GNU General Public License as published by the Free Software 7 -- Foundation; either version 3, or (at your option) any later version. 8 -- 9 -- TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 -- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 -- A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 -- 13 -- You should have received a copy of the GNU General Public License along with 14 -- TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 -- 16 17 SET search_path TO merchant; 18 19 DROP FUNCTION IF EXISTS merchant_do_increment_money_pots; 20 CREATE FUNCTION merchant_do_increment_money_pots ( 21 IN in_instance_id TEXT, 22 IN ina_money_pots_ids INT8[], 23 IN ina_increments taler_amount_currency[], 24 OUT out_not_found BOOL) 25 LANGUAGE plpgsql 26 AS $$ 27 DECLARE 28 my_merchant_id INT8; 29 i INT; 30 ini_current_pot_id INT8; 31 ini_current_increment taler_amount_currency; 32 my_totals taler_amount_currency[]; 33 currency_found BOOL; 34 j INT; 35 BEGIN 36 37 SELECT merchant_serial 38 INTO my_merchant_id 39 FROM merchant_instances 40 WHERE merchant_id=in_instance_id; 41 42 IF NOT FOUND 43 THEN 44 out_not_found = TRUE; 45 RETURN; 46 END IF; 47 48 out_not_found = FALSE; 49 50 IF ( COALESCE(array_length(ina_money_pots_ids, 1), 0) != 51 COALESCE(array_length(ina_increments, 1), 0) ) 52 THEN 53 RAISE EXCEPTION 'Array lengths must match'; 54 END IF; 55 56 FOR i IN 1..COALESCE(array_length(ina_money_pots_ids, 1),0) 57 LOOP 58 ini_current_pot_id = ina_money_pots_ids[i]; 59 ini_current_increment = ina_increments[i]; 60 61 SELECT pot_totals 62 INTO my_totals 63 FROM merchant_money_pots 64 WHERE money_pot_serial = ini_current_pot_id 65 AND merchant_serial = my_merchant_id; 66 67 IF NOT FOUND 68 THEN 69 -- If pot does not exist, we just ignore the entire 70 -- requested increment, but update the return value. 71 -- (We may have other pots to update, so we continue 72 -- to iterate!). 73 out_not_found = TRUE; 74 ELSE 75 -- Check if currency exists in pot_totals and update 76 currency_found = FALSE; 77 78 FOR j IN 1..COALESCE(array_length(my_totals, 1), 0) 79 LOOP 80 IF (my_totals[j]).currency = (ini_current_increment).currency 81 THEN 82 my_totals[j].frac 83 = my_totals[j].frac + ini_current_increment.frac; 84 my_totals[j].val 85 = my_totals[j].val + ini_current_increment.val; 86 IF my_totals[j].frac >= 100000000 87 THEN 88 my_totals[j].frac = my_totals[j].frac - 100000000; 89 my_totals[j].val = my_totals[j].val + 1; 90 END IF; 91 currency_found = TRUE; 92 EXIT; -- break out of loop 93 END IF; 94 END LOOP; 95 96 IF NOT currency_found 97 THEN 98 my_totals = array_append(my_totals, ini_current_increment); 99 END IF; 100 101 UPDATE merchant_money_pots 102 SET pot_totals = my_totals 103 WHERE money_pot_serial = ini_current_pot_id 104 AND merchant_serial = my_merchant_id; 105 106 END IF; 107 END LOOP; 108 109 END $$;