CREATE OR REPLACE FUNCTION fn_check_month_locked(p_date date)
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    IF EXISTS (
        SELECT 1
          FROM month_locks
         WHERE lock_month = date_trunc('month', p_date)
           AND is_locked = true
    ) THEN
        RAISE EXCEPTION
            '该月份已锁定，不能操作该仕訳（%）',
            to_char(p_date, 'YYYY-MM');
    END IF;
END;
$$;

CREATE OR REPLACE FUNCTION trg_journal_entries_month_lock()
RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
    IF TG_OP = 'INSERT' THEN
        PERFORM fn_check_month_locked(NEW.journal_date);
        RETURN NEW;
    END IF;

    IF TG_OP = 'UPDATE' THEN
        PERFORM fn_check_month_locked(OLD.journal_date);
        RETURN NEW;
    END IF;

    IF TG_OP = 'DELETE' THEN
        PERFORM fn_check_month_locked(OLD.journal_date);
        RETURN OLD;
    END IF;

    RETURN NULL;
END;
$$;

CREATE TRIGGER trg_journal_entries_month_lock
BEFORE INSERT OR UPDATE OR DELETE
ON journal_entries
FOR EACH ROW
EXECUTE FUNCTION trg_journal_entries_month_lock();
