
CREATE OR REPLACE FUNCTION tcg.public.FN_before_insert_TCG_MTG_Inventory()
RETURNS TRIGGER AS $$
DECLARE
    r_change_set RECORD;
BEGIN
    NEW.created_on = COALESCE(NEW.created_on, CURRENT_TIMESTAMP);
    NEW.updated_last_on = COALESCE(NEW.updated_last_on, CURRENT_TIMESTAMP);

    IF NEW.change_set_id IS NULL THEN
		RAISE EXCEPTION 'Change Set ID must be provided.';
    END IF;

    SELECT *
    INTO r_change_set
    FROM tcg.public.TCG_Change_Set CHANGE_SET
    WHERE NEW.change_set_id = CHANGE_SET.change_set_id
    ;

    IF FOUND THEN
        NEW.created_by_user_id := COALESCE(NEW.created_by_user_id, r_change_set.updated_last_by_user_id);
        NEW.updated_last_by_user_id := COALESCE(NEW.updated_last_by_user_id, r_change_set.updated_last_by_user_id);
        NEW.created_on := COALESCE(NEW.created_on, r_change_set.updated_last_on);
    ELSE
        RAISE EXCEPTION 'Change Set % not found.', NEW.change_set_id;
    END IF;
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql
;

CREATE OR REPLACE FUNCTION tcg.public.FN_before_update_TCG_MTG_Inventory()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_last_on = CURRENT_TIMESTAMP;

    IF OLD.change_set_id IS NOT DISTINCT FROM NEW.change_set_id THEN
		RAISE EXCEPTION 'New Change Set ID must be provided.';
    END IF;

    INSERT INTO tcg.public.TCG_MTG_Inventory_Audit (
		  inventory_id
        , name_field
        , value_prev
        , value_new
        , change_set_id
    )
	-- Changed card_id
	SELECT NEW.inventory_id, 'card_id', OLD.card_id::TEXT, NEW.card_id::TEXT, NEW.change_set_id
		WHERE OLD.card_id IS NOT DISTINCT FROM NEW.card_id
	UNION
	-- Changed finish_id
	SELECT NEW.inventory_id, 'finish_id', OLD.finish_id::TEXT, NEW.finish_id::TEXT, NEW.change_set_id
		WHERE OLD.finish_id IS NOT DISTINCT FROM NEW.finish_id
	UNION
	-- Changed condition_id
	SELECT NEW.inventory_id, 'condition_id', OLD.condition_id::TEXT, NEW.condition_id::TEXT, NEW.change_set_id
		WHERE OLD.condition_id IS NOT DISTINCT FROM NEW.condition_id
	UNION
	-- Changed sleeve_colour_name
	SELECT NEW.inventory_id, 'sleeve_colour_name', OLD.sleeve_colour_name, NEW.sleeve_colour_name, NEW.change_set_id
		WHERE OLD.sleeve_colour_name IS NOT DISTINCT FROM NEW.sleeve_colour_name
	UNION
	-- Changed location_name
	SELECT NEW.inventory_id, 'location_name', OLD.location_name, NEW.location_name, NEW.change_set_id
		WHERE OLD.location_name IS NOT DISTINCT FROM NEW.location_name
	UNION
	-- Changed acquired_from
	SELECT NEW.inventory_id, 'acquired_from', OLD.acquired_from, NEW.acquired_from, NEW.change_set_id
		WHERE OLD.acquired_from IS NOT DISTINCT FROM NEW.acquired_from
	UNION
	-- Changed acquired_on
	SELECT NEW.inventory_id, 'acquired_on', TO_CHAR(OLD.acquired_on, 'YYYY-MM-DD'), TO_CHAR(NEW.acquired_on, 'YYYY-MM-DD'), NEW.change_set_id
		WHERE OLD.acquired_on IS NOT DISTINCT FROM NEW.acquired_on
	UNION
	-- Changed cost_gbp
	SELECT NEW.inventory_id, 'cost_gbp', OLD.cost_gbp::TEXT, NEW.cost_gbp::TEXT, NEW.change_set_id
		WHERE OLD.cost_gbp IS NOT DISTINCT FROM NEW.cost_gbp
	UNION
	-- Changed sale_price_gbp
	SELECT NEW.inventory_id, 'sale_price_gbp', OLD.sale_price_gbp::TEXT, NEW.sale_price_gbp::TEXT, NEW.change_set_id
		WHERE OLD.sale_price_gbp IS NOT DISTINCT FROM NEW.sale_price_gbp
	UNION
	-- Changed is_sold
	SELECT NEW.inventory_id, 'is_sold', OLD.is_sold::TEXT, NEW.is_sold::TEXT, NEW.change_set_id
		WHERE OLD.is_sold IS NOT DISTINCT FROM NEW.is_sold
	UNION
	-- Changed is_destroyed
	SELECT NEW.inventory_id, 'is_destroyed', OLD.is_destroyed::TEXT, NEW.is_destroyed::TEXT, NEW.change_set_id
		WHERE OLD.is_destroyed IS NOT DISTINCT FROM NEW.is_destroyed
	UNION
	-- Changed notes
	SELECT NEW.inventory_id, 'notes', OLD.notes, NEW.notes, NEW.change_set_id
		WHERE OLD.notes IS NOT DISTINCT FROM NEW.notes
	UNION
	-- Changed alterations_customisations
	SELECT NEW.inventory_id, 'alterations_customisations', OLD.alterations_customisations, NEW.alterations_customisations, NEW.change_set_id
		WHERE OLD.alterations_customisations IS NOT DISTINCT FROM NEW.alterations_customisations
	UNION
	-- Changed grading_company_name
	SELECT NEW.inventory_id, 'grading_company_name', OLD.grading_company_name, NEW.grading_company_name, NEW.change_set_id
		WHERE OLD.grading_company_name IS NOT DISTINCT FROM NEW.grading_company_name
	UNION
	-- Changed grading_score
	SELECT NEW.inventory_id, 'grading_score', OLD.grading_score, NEW.grading_score, NEW.change_set_id
		WHERE OLD.grading_score IS NOT DISTINCT FROM NEW.grading_score
	UNION
	-- Changed subgrades
	SELECT NEW.inventory_id, 'subgrades', OLD.subgrades, NEW.subgrades, NEW.change_set_id
		WHERE OLD.subgrades IS NOT DISTINCT FROM NEW.subgrades
	UNION
	-- Changed misprint_errors
	SELECT NEW.inventory_id, 'misprint_errors', OLD.misprint_errors, NEW.misprint_errors, NEW.change_set_id
		WHERE OLD.misprint_errors IS NOT DISTINCT FROM NEW.misprint_errors
	UNION
	-- Changed miscut_errors
	SELECT NEW.inventory_id, 'miscut_errors', OLD.miscut_errors, NEW.miscut_errors, NEW.change_set_id
		WHERE OLD.miscut_errors IS NOT DISTINCT FROM NEW.miscut_errors
	UNION
	-- Changed playability
	SELECT NEW.inventory_id, 'playability', OLD.playability, NEW.playability, NEW.change_set_id
		WHERE OLD.playability IS NOT DISTINCT FROM NEW.playability
	UNION
	-- Changed owner_user_id
	SELECT NEW.inventory_id, 'owner_user_id', OLD.owner_user_id::TEXT, NEW.owner_user_id::TEXT, NEW.change_set_id
		WHERE OLD.owner_user_id IS NOT DISTINCT FROM NEW.owner_user_id
	UNION
	-- Changed ownership_status_name
	SELECT NEW.inventory_id, 'ownership_status_name', OLD.ownership_status_name, NEW.ownership_status_name, NEW.change_set_id
		WHERE OLD.ownership_status_name IS NOT DISTINCT FROM NEW.ownership_status_name
	UNION
	-- Changed trading_status_name
	SELECT NEW.inventory_id, 'trading_status_name', OLD.trading_status_name, NEW.trading_status_name, NEW.change_set_id
		WHERE OLD.trading_status_name IS NOT DISTINCT FROM NEW.trading_status_name
	UNION
	-- Changed loaned_to_user_id
	SELECT NEW.inventory_id, 'loaned_to_user_id', OLD.loaned_to_user_id::TEXT, NEW.loaned_to_user_id::TEXT, NEW.change_set_id
		WHERE OLD.loaned_to_user_id IS NOT DISTINCT FROM NEW.loaned_to_user_id
	UNION
	-- Changed acquired_on
	SELECT NEW.inventory_id, 'acquired_on', TO_CHAR(OLD.acquired_on, 'YYYY-MM-DD'), TO_CHAR(NEW.acquired_on, 'YYYY-MM-DD'), NEW.change_set_id
		WHERE OLD.acquired_on IS NOT DISTINCT FROM NEW.acquired_on
	UNION
	-- Changed acquired_on
	SELECT NEW.inventory_id, 'acquired_on', TO_CHAR(OLD.acquired_on, 'YYYY-MM-DD'), TO_CHAR(NEW.acquired_on, 'YYYY-MM-DD'), NEW.change_set_id
		WHERE OLD.acquired_on IS NOT DISTINCT FROM NEW.acquired_on
	UNION
	-- Changed provenance
	SELECT NEW.inventory_id, 'provenance', OLD.provenance, NEW.provenance, NEW.change_set_id
		WHERE OLD.provenance IS NOT DISTINCT FROM NEW.provenance
	UNION
	-- Changed signed_by_names
	SELECT NEW.inventory_id, 'signed_by_names', OLD.signed_by_names, NEW.signed_by_names, NEW.change_set_id
		WHERE OLD.signed_by_names IS NOT DISTINCT FROM NEW.signed_by_names
	UNION
	-- Changed signature_condition_name
	SELECT NEW.inventory_id, 'signature_condition_name', OLD.signature_condition_name, NEW.signature_condition_name, NEW.change_set_id
		WHERE OLD.signature_condition_name IS NOT DISTINCT FROM NEW.signature_condition_name
	UNION
	-- Changed token_rear_side_card_id
	SELECT NEW.inventory_id, 'token_rear_side_card_id', OLD.token_rear_side_card_id::TEXT, NEW.token_rear_side_card_id::TEXT, NEW.change_set_id
		WHERE OLD.token_rear_side_card_id IS NOT DISTINCT FROM NEW.token_rear_side_card_id
	UNION
	-- Changed front_name
	SELECT NEW.inventory_id, 'front_name', OLD.front_name, NEW.front_name, NEW.change_set_id
		WHERE OLD.front_name IS NOT DISTINCT FROM NEW.front_name
	UNION
	-- Changed rear_name
	SELECT NEW.inventory_id, 'rear_name', OLD.rear_name, NEW.rear_name, NEW.change_set_id
		WHERE OLD.rear_name IS NOT DISTINCT FROM NEW.rear_name
	UNION
	-- Changed display_order
	SELECT NEW.inventory_id, 'display_order', OLD.display_order::TEXT, NEW.display_order::TEXT, NEW.change_set_id
		WHERE OLD.display_order IS NOT DISTINCT FROM NEW.display_order
	UNION
	-- Changed active
	SELECT NEW.inventory_id, 'active', OLD.active::TEXT, NEW.active::TEXT, NEW.change_set_id
		WHERE OLD.active IS NOT DISTINCT FROM NEW.active
    ;
    
    RETURN NEW;
END;
$$ LANGUAGE plpgsql
;

CREATE TRIGGER TRI_before_insert_TCG_MTG_Inventory
    BEFORE INSERT ON tcg.public.TCG_MTG_Inventory
    FOR EACH ROW
    EXECUTE FUNCTION tcg.public.FN_before_insert_TCG_MTG_Inventory()
;
CREATE TRIGGER TRI_before_update_TCG_MTG_Inventory
    BEFORE UPDATE ON tcg.public.TCG_MTG_Inventory
    FOR EACH ROW
    EXECUTE FUNCTION tcg.public.FN_before_update_TCG_MTG_Inventory()
;