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


-- DROP FUNCTION back_office.set_eps_transaction(int4, int4, bool);

CREATE OR REPLACE FUNCTION back_office.set_eps_transaction(p_operation_id integer DEFAULT NULL::integer, p_incoming_order_id integer DEFAULT NULL::integer, p_is_default boolean DEFAULT true)
 RETURNS TABLE(success boolean, eps_transaction_source_id integer, eps_transaction_id integer)
 LANGUAGE plpgsql
AS $function$
-- ===================================================================================
-- Запись данных витрины ЕПС при синхронизации с операциями и платежными поручениями
-- Параметры:
-- p_operation_id - ИД операции
-- p_incoming_order_id - ИД входящего платежного поручения
-- Создание: 22.09.2026 dv.pakhomov
-- ===================================================================================
DECLARE 
    v_eps_id integer;
    v_eps_transaction_source_id integer;
BEGIN
    DROP TABLE IF EXISTS tmp_eps_transactions;

    CREATE TEMP TABLE IF NOT EXISTS tmp_eps_transactions
    (
        eps_transaction_source_id integer,
        eps_transaction_id integer,
        eps_id integer,
        success boolean GENERATED ALWAYS AS ( eps_transaction_source_id IS NOT NULL 
            AND eps_transaction_id IS NOT NULL ) STORED
    )
    ;

    -- раскраска витрины ЕПС для операции
    IF p_operation_id IS NOT NULL
    THEN    
        INSERT INTO back_office.eps_transaction_source 
        ( operation_id )
        SELECT o.id  
        FROM back_office.operation o 
            INNER JOIN back_office.eps_operation_type eot 
            ON eot.operation_type_id = o.operation_type_id
            INNER JOIN ourpension.eps e 
            ON e.id = eot.eps_id 
        WHERE p_operation_id IS NOT NULL
            AND o.id = p_operation_id
            AND CURRENT_DATE 
                BETWEEN e.start_date AND COALESCE( e.end_date, CURRENT_DATE )            
        GROUP BY o.id
        RETURNING id
        INTO v_eps_transaction_source_id;
        
        IF v_eps_transaction_source_id IS NOT NULL
        THEN
            WITH cte_insert_eps_transaction AS
            (   -- добавление в транзакции ЕПС
                INSERT INTO back_office.eps_transaction
                (   eps_transaction_source_id,
                    eps_id,
                    oper_date,
                    operation_sum,
                    contract_id_dt,
                    individual_id_dt,
                    entity_id_dt,
                    contract_id_ct,
                    individual_id_ct,
                    entity_id_ct
                )
                SELECT 
                    v_eps_transaction_source_id,
                    eot.eps_id,
                    o.effective_date::timestamp as oper_date,
                    t."value" as operation_sum,
                    a_dt.owner_contract_id as contract_id_dt,
                    a_dt.owner_individual_id as individual_id_dt,
                    a_dt.owner_entity_id as entity_id_dt,
                    a_ct.owner_contract_id as contract_id_ct,
                    a_ct.owner_individual_id as individual_id_ct,
                    a_ct.owner_entity_id as entity_id_ct
                FROM back_office.operation o                
                    INNER JOIN back_office.eps_operation_type eot 
                    ON eot.operation_type_id = o.operation_type_id
                    INNER JOIN back_office.transaction t
                    ON t.operation_id = o.id
                    LEFT JOIN back_office.account a_dt 
                    ON a_dt.id = t.credit_account_id
                    LEFT JOIN back_office.account a_ct 
                    ON a_ct.id = t.debit_account_id
                WHERE o.id = p_operation_id
                RETURNING 
                    id as eps_transaction_id,
                    eps_id
            )
            -- добавление в возвращаемый набор данных
            INSERT INTO tmp_eps_transactions
            (   eps_transaction_source_id,            
                eps_transaction_id,            
                eps_id            
            )
            SELECT
                v_eps_transaction_source_id as eps_transaction_source_id,
                ciet.eps_transaction_id,
                ciet.eps_id
            FROM cte_insert_eps_transaction ciet
            ;
        END IF;
    END IF;

    -- раскраска витрины ЕПС для платежки
    IF p_incoming_order_id IS NOT NULL
    THEN    
        -- попытка определить значение ЕПС исходя из связи типа платежа с кодом ЕПС
        INSERT INTO tmp_eps_transactions
        ( eps_id )
        SELECT ote.eps_id
        FROM back_office.incoming_order io
            INNER JOIN back_office.order_payment_type_eps ote 
            ON ote.order_payment_type_id = io.order_payment_type_id
            INNER JOIN ourpension.eps e 
            ON e.id = ote.eps_id 
        WHERE io.id = p_incoming_order_id
            AND CURRENT_DATE 
                BETWEEN e.start_date AND COALESCE( e.end_date, CURRENT_DATE );
           
        IF p_is_default -- подстановка по умолчанию включена
            AND NOT EXISTS
                (   SELECT 1
                    FROM tmp_eps_transactions
                    LIMIT 1
                ) -- определить значение ЕПС по-хорошему не получилось
        THEN
            -- определяем значение по умолчанию для вида деятельности
            WITH cte_eps_service_type AS
            (   -- Коды ЕПС по умолчанию, соответствующие видам деятельности
                SELECT *
                FROM
                    (   VALUES
                        (   'PDS',          '4002' ),
                        (   'NPO',          '4001' ),
                        (   'OPS',          '3002' )
                    ) v (   service_type,   eps_code )
            )
            INSERT INTO tmp_eps_transactions
            ( eps_id )
            SELECT e.id
            FROM back_office.incoming_order io
                INNER JOIN back_office.order_payment_type ot 
                ON ot.id = io.order_payment_type_id
                INNER JOIN cte_eps_service_type cest
                ON cest.service_type = ot."service_type"
                INNER JOIN ourpension.eps e 
                ON e.code = cest.eps_code 
            WHERE io.id = p_incoming_order_id;
        END IF;

        IF EXISTS
            (   SELECT 1
                FROM tmp_eps_transactions
                LIMIT 1
            ) -- определить значение ЕПС получилось
        THEN
            -- добавление основания движения ЕПС для платежек
            INSERT INTO back_office.eps_transaction_source 
            ( incoming_order_id )
            VALUES
            ( p_incoming_order_id )
            RETURNING id
            INTO v_eps_transaction_source_id;
                
            -- добавление данных движения ЕПС
            WITH cte_insert_eps_transaction AS
            (   INSERT INTO back_office.eps_transaction
                (   eps_transaction_source_id,
                    eps_id,
                    oper_date,
                    operation_sum,
                    contract_id_ct,
                    individual_id_ct,
                    entity_id_ct
                )
                SELECT 
                    v_eps_transaction_source_id, 
                    et.eps_id,
                    CAST( io."date" AS timestamp ) as oper_date,
                    io.value as operation_sum,
                    io.contract_id as contract_id_ct,
                    io.individual_id as individual_id_ct,
                    io.entity_id as entity_id_ct
                FROM back_office.incoming_order io
                    CROSS JOIN tmp_eps_transactions et
                WHERE io.id = p_incoming_order_id
                RETURNING 
                    id,
                    eps_id
            )
            -- фиксируем данные для возврата
            UPDATE tmp_eps_transactions
            SET 
                eps_transaction_source_id = v_eps_transaction_source_id,
                eps_transaction_id = ciet.id
            FROM cte_insert_eps_transaction ciet
            WHERE ciet.eps_id = tmp_eps_transactions.eps_id;
        END IF;
    END IF;
    
    IF NOT EXISTS
        (   SELECT 1
            FROM tmp_eps_transactions
            LIMIT 1
        ) -- с окраской не получилось
    THEN
        -- добавляем пустую запись
        INSERT INTO tmp_eps_transactions
        ( eps_transaction_source_id )
        VALUES
        ( NULL );
    END IF;    

    RETURN QUERY
    SELECT
        et.success,
        et.eps_transaction_source_id,
        et.eps_transaction_id
    FROM tmp_eps_transactions et
    ;
        
END;
$function$
;