merchant

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

pg_update_inventory_locked.sql (2857B)


      1 --
      2 -- This file is part of TALER
      3 -- Copyright (C) 2026 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 
     18 -- Trigger function that adjusts merchant_inventory.total_locked(_frac)
     19 -- whenever a row in one of the lock tables is inserted, updated or
     20 -- deleted (including cascade deletes when orders expire or are removed).
     21 CREATE OR REPLACE FUNCTION update_inventory_locked()
     22   RETURNS TRIGGER
     23   LANGUAGE plpgsql
     24 AS $$
     25 DECLARE
     26   my_product_serial INT8;
     27   my_delta NUMERIC := 0;
     28 BEGIN
     29   CASE TG_OP
     30     WHEN 'INSERT' THEN
     31       my_product_serial := NEW.product_serial;
     32       my_delta := NEW.total_locked::NUMERIC * 1000000
     33                 + NEW.total_locked_frac::NUMERIC;
     34     WHEN 'DELETE' THEN
     35       my_product_serial := OLD.product_serial;
     36       my_delta := - (OLD.total_locked::NUMERIC * 1000000
     37                      + OLD.total_locked_frac::NUMERIC);
     38     WHEN 'UPDATE' THEN
     39       my_product_serial := NEW.product_serial;
     40       my_delta := (NEW.total_locked::NUMERIC * 1000000
     41                    + NEW.total_locked_frac::NUMERIC)
     42                    - (OLD.total_locked::NUMERIC * 1000000
     43                       + OLD.total_locked_frac::NUMERIC);
     44     ELSE
     45       RETURN NULL;
     46   END CASE;
     47   IF (my_delta <> 0)
     48   THEN
     49     -- Use div()/% (truncating, never rounding) to split the combined
     50     -- micro-unit amount back into whole and fractional parts.
     51     UPDATE merchant_inventory
     52        SET total_locked =
     53              div (total_locked::NUMERIC * 1000000
     54                   + total_locked_frac::NUMERIC + my_delta,
     55                   1000000)::INT8,
     56            total_locked_frac =
     57              ((total_locked::NUMERIC * 1000000
     58                + total_locked_frac::NUMERIC + my_delta) % 1000000)::INT4
     59      WHERE product_serial = my_product_serial;
     60   END IF;
     61   RETURN NULL;
     62 END $$;
     63 
     64 COMMENT ON FUNCTION update_inventory_locked
     65   IS 'Trigger function that adjusts merchant_inventory.total_locked(_frac) whenever a row in one of the lock tables is inserted, updated or deleted (including cascade deletes when orders expire or are removed). The same trigger is installed on BOTH the merchant_inventory_locks and merchant_order_locks tables for INSERT, UPDATE and DELETE (and thus relies on the fact that the columns we are about have the same names in both tables).';