merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

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 $$;