-- -- This file is part of TALER -- Copyright (C) 2024 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 -- CREATE OR REPLACE FUNCTION merchant_do_insert_product ( IN in_instance_id TEXT, IN in_product_id TEXT, IN in_description TEXT, IN in_description_i18n BYTEA, IN in_unit TEXT, IN in_image TEXT, IN in_taxes BYTEA, IN in_price taler_amount_currency, IN in_total_stock INT8, IN in_address BYTEA, IN in_next_restock INT8, IN in_minimum_age INT4, IN ina_categories INT8[], OUT out_no_instance BOOL, OUT out_conflict BOOL, OUT out_no_cat INT8) LANGUAGE plpgsql AS $$ DECLARE my_merchant_id INT8; my_product_serial INT8; i INT8; ini_cat INT8; BEGIN -- Which instance are we using? SELECT merchant_serial INTO my_merchant_id FROM merchant_instances WHERE merchant_id=in_instance_id; IF NOT FOUND THEN out_no_instance=TRUE; out_conflict=FALSE; out_no_cat=NULL; RETURN; END IF; out_no_instance=FALSE; INSERT INTO merchant_inventory (merchant_serial ,product_id ,description ,description_i18n ,unit ,image ,taxes ,price ,total_stock ,address ,next_restock ,minimum_age ) VALUES ( my_merchant_id ,in_product_id ,in_description ,in_description_i18n ,in_unit ,in_image ,in_taxes ,in_price ,in_total_stock ,in_address ,in_next_restock ,in_minimum_age) ON CONFLICT (merchant_serial, product_id) DO NOTHING RETURNING product_serial INTO my_product_serial; IF NOT FOUND THEN -- Check for idempotency SELECT product_serial INTO my_product_serial FROM merchant_inventory WHERE merchant_serial=my_merchant_id AND product_id=in_product_id AND description=in_description AND description_i18n=in_description_i18n AND unit=in_unit AND image=in_image AND taxes=in_taxes AND price=in_price AND total_stock=in_total_stock AND address=in_address AND next_restock=in_next_restock AND minimum_age=in_minimum_age; IF NOT FOUND THEN out_conflict=TRUE; out_no_cat=NULL; RETURN; END IF; -- Check categories match as well FOR i IN 1..COALESCE(array_length(ina_categories,1),0) LOOP ini_cat=ina_categories[i]; PERFORM FROM merchant_product_categories WHERE product_serial=my_product_serial AND category_serial=ini_cat; IF NOT FOUND THEN out_conflict=TRUE; out_no_cat=NULL; RETURN; END IF; END LOOP; -- Also check there are no additional categories -- in either set. SELECT COUNT(*) INTO i FROM merchant_product_categories WHERE product_serial=my_product_serial; IF i != array_length(ina_categories,1) THEN out_conflict=TRUE; out_no_cat=NULL; RETURN; END IF; -- Is idempotent! out_conflict=FALSE; out_no_cat=NULL; RETURN; END IF; out_conflict=FALSE; -- Add categories FOR i IN 1..COALESCE(array_length(ina_categories,1),0) LOOP ini_cat=ina_categories[i]; INSERT INTO merchant_product_categories (product_serial ,category_serial) VALUES (my_product_serial ,ini_cat) ON CONFLICT DO NOTHING; IF NOT FOUND THEN out_no_cat=i; RETURN; END IF; END LOOP; -- Success! out_no_cat=NULL; END $$;