Загрузка данных


CREATE OR REPLACE FUNCTION report.delete_fns_reference_request(
    p_model_file_id integer
)
RETURNS integer
LANGUAGE plpgsql
AS $function$
DECLARE
    v_register_id integer;
    v_is_sent_to_fns boolean;
    v_files_count integer;
BEGIN
    IF p_model_file_id IS NULL THEN
        RAISE EXCEPTION 'Не указан идентификатор файла запроса';
    END IF;

    /*
     * Получаем и блокируем файл и реестр на время удаления.
     */
    SELECT m.register_id
      INTO v_register_id
      FROM dev.model_file_to_verification m
      JOIN report.smev_register sr
        ON sr.id = m.register_id
     WHERE m.id = p_model_file_id
     FOR UPDATE OF m, sr;

    IF NOT FOUND THEN
        RAISE EXCEPTION
            'Запрос с идентификатором файла % не найден',
            p_model_file_id;
    END IF;

    /*
     * Блокируем все строки журнала данного запроса.
     */
    PERFORM 1
      FROM report.fns_reference_request_journal fj
     WHERE fj.model_file_to_verification_id = p_model_file_id
     FOR UPDATE;

    IF NOT FOUND THEN
        RAISE EXCEPTION
            'Запись запроса в журнале не найдена';
    END IF;

    /*
     * Повторная серверная проверка:
     * отправлённый запрос удалять запрещено.
     */
    SELECT COALESCE(
               bool_or(COALESCE(fj.is_sent_to_fns, false)),
               false
           )
      INTO v_is_sent_to_fns
      FROM report.fns_reference_request_journal fj
     WHERE fj.model_file_to_verification_id = p_model_file_id;

    IF v_is_sent_to_fns THEN
        RAISE EXCEPTION
            'Удаление невозможно: запрос уже отправлен в ФНС';
    END IF;

    /*
     * Защита от удаления общего реестра.
     */
    SELECT count(*)
      INTO v_files_count
      FROM dev.model_file_to_verification m
     WHERE m.register_id = v_register_id;

    IF v_files_count <> 1 THEN
        RAISE EXCEPTION
            'Удаление невозможно: реестр % связан с несколькими файлами',
            v_register_id;
    END IF;

    /*
     * Убираем сохранённое выделение удаляемой строки.
     */
    DELETE FROM tools.selection s
     USING report.fns_reference_request_journal fj
     WHERE fj.model_file_to_verification_id = p_model_file_id
       AND s.row_id = fj.id
       AND s.code = 'VxvzLyks';

    /*
     * Удаляем всю сущность запроса.
     */
    DELETE FROM report.fns_reference_request_journal
     WHERE model_file_to_verification_id = p_model_file_id;

    DELETE FROM dev.model_file_to_verification
     WHERE id = p_model_file_id;

    DELETE FROM report.smev_register
     WHERE id = v_register_id;

    IF NOT FOUND THEN
        RAISE EXCEPTION
            'Не удалось удалить реестр %',
            v_register_id;
    END IF;

    RETURN 1;
END;
$function$;