--
-- 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/>
--

DROP FUNCTION IF EXISTS merchant_do_delete_product;
CREATE FUNCTION merchant_do_delete_product (
  IN in_product_id TEXT,
  IN in_force BOOLEAN,
  OUT out_not_found BOOLEAN,
  OUT out_locked BOOLEAN)
LANGUAGE plpgsql
AS $$
DECLARE
  my_product_serial INT8;
  my_has_locks BOOLEAN;
BEGIN
  SELECT product_serial
    INTO my_product_serial
    FROM merchant_inventory
   WHERE product_id = in_product_id;
  IF NOT FOUND
  THEN
    out_not_found = TRUE;
    out_locked = FALSE;
    RETURN;
  END IF;
  out_not_found = FALSE;

  my_has_locks = (
       EXISTS (SELECT 1
                 FROM merchant_order_locks
                WHERE product_serial = my_product_serial)
    OR EXISTS (SELECT 1
                 FROM merchant_inventory_locks
                WHERE product_serial = my_product_serial));
  IF (my_has_locks AND NOT in_force)
  THEN
    -- Refuse: the product is locked and the caller did not force deletion.
    out_locked = TRUE;
    RETURN;
  END IF;
  out_locked = FALSE;

  IF (my_has_locks)
  THEN
    -- Release any locks first.  merchant_order_locks has no ON DELETE CASCADE
    -- on product_serial, so its rows would otherwise block the deletion;
    -- merchant_inventory_locks rows would cascade, but we delete them
    -- explicitly so that the total_locked counter trigger stays consistent.
    DELETE FROM merchant_order_locks
      WHERE product_serial = my_product_serial;
    DELETE FROM merchant_inventory_locks
      WHERE product_serial = my_product_serial;
  END IF;
  DELETE FROM merchant_inventory
    WHERE product_serial = my_product_serial;
END $$;

COMMENT ON FUNCTION merchant_do_delete_product(TEXT, BOOLEAN)
  IS 'Deletes a product. Returns out_not_found=TRUE if the product does not'
     ' exist. If the product is locked and in_force is FALSE, returns'
     ' out_locked=TRUE without deleting. If in_force is TRUE, any locks'
     ' are released and the product is deleted.';
