Загрузка данных
источник данных для заполнения полей "Предыдущий страховщик" и "Следующий страховщик"
-- DROP FUNCTION ourpension.get_contract_fields_main(int4);
CREATE OR REPLACE FUNCTION ourpension.get_contract_fields_main(v_contract_id integer)
RETURNS TABLE(id integer, number json, date text, investor character varying, fund_name character varying, fund_name_short character varying, service_type_rus text, invest_type_text text, contract_life_cicle character varying, sale_channel_id integer, sale_channel_text character varying, comment text, action_date text, agent_code character varying, agent_name text, previous_insurer_name character varying, new_insurer_name character varying, annulled_date text, create_date text, fund_branch_name character varying, contract_class_name character varying, name_in_pfr character varying, contract_type text, affiliate_program_contract_id integer, affiliate_program_contract_text text, family_member boolean, department_type character varying)
LANGUAGE plpgsql
AS $function$
BEGIN
-- Функция выводит поля Общей информации по договору. Выделено для облегчения запроса в модели Карточки договора.
-- Создано: 01.2026 dv.pakhomov
-- Изменения:
-- 24.03.2026 dv.pakhomov Убрал задвоение записей из-за неправильного подключения ourpension.contract_class_history
-- 24.04.2026 dv.pakhomov Получение названий фондов из справочника ourpension.fund
RETURN query
WITH s AS(
SELECT
c.id,
CASE
WHEN c.service_type = 'NPO' AND c.individual_id IS NOT NULL THEN 'ИПП'
WHEN c.service_type = 'NPO' AND c.entity_id IS NOT NULL THEN 'КПП'
WHEN c.service_type = 'PDS' THEN 'ДДС'
ELSE ''
END as contract_type,
to_json(c.number) as number,
c.date,
coalesce(e.short_name, i.last_name || ' ' || i.first_name || ' ' || i.middle_name) as investor,
coalesce(uat.activity_rus_type, 'ОПС') as service_type_rus,
case c.invest_type
when 1 then 'Инвестиционный'
when 2 then 'Страховой'
end as invest_type_text,
c.sale_channel_id,
c.comment,
ha.short_name as department_type,
ag.code as agent_code,
coalesce(ag.last_name,'') || ' ' || left(coalesce(ag.first_name, ''), 1) || '.' || coalesce(left(ag.middle_name, 1) || '.', '') as agent_name,
pi.previous_insurer_pfr_name previous_insurer_name,
ni.new_insurer_pfr_name new_insurer_name,
cch.begin_date as create_date,
fb.name as fund_branch_name,
cch.class_name,
c.affiliate_program_contract_id,
to_json( CONCAT( ce.number, ' (', ea.short_name, ')' ) )::text as affiliate_program_contract_text,
fsg.name_full as fund_name,
fsg.name_short as fund_name_short,
fsr.name_in_pfr as name_in_pfr,
c.family_member
FROM ourpension.contract c
LEFT JOIN ourpension.individual i ON c.individual_id = i.id
LEFT JOIN ourpension.fund fsg ON fsg.id = c.sign_fund_id -- Заключивший фонд
LEFT JOIN ourpension.fund fsr ON fsr.id = c.fund_id -- Фонд-источник
LEFT JOIN ourpension.agent ag
ON ag.id = c.agent_id
LEFT JOIN ourpension.fund_branch fb
ON fb.id = ag.fund_branch_id
LEFT JOIN ourpension.uv_activity_type uat ON c.client_type = uat.client_type AND c.service_type = uat.activity_eng_type
LEFT JOIN ourpension.ops_get_contract_new_insurer(c.id) ni ON c.service_type = 'OPS'
LEFT JOIN ourpension.ops_get_contract_previous_insurer(c.id) pi ON c.service_type = 'OPS'
LEFT JOIN ourpension.contract ce
ON ce.id = c.affiliate_program_contract_id
LEFT JOIN ourpension.entity ea
ON ea.id = ce.entity_id
LEFT JOIN ourpension.holding ha
ON ha.id = ea.holding_id
LEFT JOIN LATERAL
(
SELECT
cch1.begin_date,
cc1."name" AS class_name
FROM ourpension.contract_class_history cch1
INNER JOIN ourpension.contract_classes cc1 ON cch1.class_id = cc1.id
WHERE cch1.contract_id = c.id
ORDER BY cch1.begin_date DESC
LIMIT 1
) cch ON true
LEFT JOIN ourpension.entity e ON e.id = c.entity_id
WHERE c.id = v_contract_id
),
cte_statuses_l AS
( -- Последний (актуальный) статус
SELECT
cs1."name" AS status_name,
CASE WHEN sh1.code IN ( 'EA0', 'JA0', 'PA0' ) THEN sh1.status_date END as annulled_date
FROM ourpension.contract_statuses_history sh1
INNER JOIN ourpension.contract_statuses cs1 on cs1.code = sh1.code
WHERE sh1.contract_id = v_contract_id
AND CURRENT_TIMESTAMP BETWEEN
sh1.status_date AND COALESCE( sh1.status_end_date, 'infinity' )
LIMIT 1
),
cte_statuses_a AS
( -- Статус введения в действие
SELECT sh.status_date
FROM ourpension.contract_statuses_history sh
WHERE sh.contract_id = v_contract_id
AND sh.code IN ( 'CA0', 'HA0', 'MA0' )
ORDER BY sh.status_date
LIMIT 1
)
SELECT
s.id,
s.number,
to_char(s.date, 'dd.MM.yyyy') as "date",
s.investor,
s.fund_name,
s.fund_name_short,
s.service_type_rus,
s.invest_type_text,
csl.status_name as contract_life_cicle,
s.sale_channel_id,
sc.name as sale_channel_text,
s.comment,
to_char(csa.status_date, 'dd.MM.yyyy') as action_date,
s.agent_code,
s.agent_name,
s.previous_insurer_name,
s.new_insurer_name,
to_char(csl.annulled_date, 'dd.MM.yyyy') as annulled_date,
to_char(s.create_date, 'dd.MM.yyyy') as create_date,
s.fund_branch_name,
s.class_name as contract_class_name,
s.name_in_pfr,
s.contract_type,
s.affiliate_program_contract_id,
s.affiliate_program_contract_text,
s.family_member,
s.department_type
FROM s
INNER JOIN cte_statuses_l csl ON true
LEFT JOIN ourpension.information_source sc on sc.id = s.sale_channel_id
LEFT JOIN cte_statuses_a csa ON true;
END;
$function$
;
-- DROP FUNCTION ourpension.ops_get_contract_previous_insurer(int4);
CREATE OR REPLACE FUNCTION ourpension.ops_get_contract_previous_insurer(p_contract_id integer)
RETURNS TABLE(previous_insurer_pfr_name character varying, previous_insurer_inn character varying, fund_id integer, privious_insurer_source character varying)
LANGUAGE plpgsql
AS $function$
DECLARE
v_previous_insurer_pfr_name varchar(500) = null;
v_previous_insurer_inn varchar(100) = null;
v_previous_insurer_fund_id int = null::int;
v_count_ops int =0;
begin
select count(*)
into v_count_ops
from ourpension.contract c
where c.id = p_contract_id
and c.service_type = 'OPS';
if v_count_ops = 0 then
return query
select null::varchar, null::varchar, null::int, 'Не определен'::varchar(255);
else
select su.previos_insurer_pfr_name, su.previos_insurer_inn, f.id fund_id
into v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id
from report.smev_uier su
join ourpension.fund f on f.inn = su.previos_insurer_inn
join ourpension.contract c on su.contract_number = c.number and su.contract_date = c.date
where su.uier_document_type_id in (1, 4) and c.id = p_contract_id;
if not (v_previous_insurer_pfr_name is null or v_previous_insurer_inn is null or v_previous_insurer_fund_id is null) then
return query
select v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id, 'ЕРЗЛ'::varchar(255);
else
select f.name_in_pfr, f.inn, f.id
into v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id
from ourpension.court_decision_data cdd
join ourpension.court_decision cd on cd.id = cdd.court_decision_id
join ourpension.fund f on f.id = cd.proper_insurer_id
where cdd.contract_id = p_contract_id;
if not (v_previous_insurer_pfr_name is null or v_previous_insurer_inn is null or v_previous_insurer_fund_id is null) then
return query
select v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id, 'Решение суда'::varchar(255);
else
select f.name_in_pfr, f.inn, f.id
into v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id
from ourpension.sharer s
join back_office."account" a on a.owner_sharer_id = s.id
join back_office.transaction t on t.credit_account_id = a.id
join back_office.operation o on o.id = t.operation_id
join back_office.operation_document od on o.operation_document_id = od.id
join ourpension.enums e on e.id = od.distribution_reason_enums_id and e.enum_value_abbr = 'ПереходВФонд1ыйТранш'
join back_office.incoming_order_operation ioo on ioo.operation_id = o.id
join back_office.incoming_order io on io.id = ioo.incoming_order_id
join ourpension.fund f on f.entity_id = io.payer_entity_id
where s.contract_id = p_contract_id
order by io.date asc
limit 1;
if not (v_previous_insurer_pfr_name is null or v_previous_insurer_inn is null or v_previous_insurer_fund_id is null) then
return query
select v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id, 'Первый транш'::varchar(255);
else
return query
select v_previous_insurer_pfr_name, v_previous_insurer_inn, v_previous_insurer_fund_id, 'Не определен'::varchar(255);
end if;
end if;
end if;
end if;
end
$function$
;
-- DROP FUNCTION ourpension.ops_get_contract_new_insurer(int4);
CREATE OR REPLACE FUNCTION ourpension.ops_get_contract_new_insurer(contract_id integer)
RETURNS TABLE(new_insurer_pfr_name character varying, new_insurer_inn character varying, fund_id integer, new_insurer_source character varying)
LANGUAGE plpgsql
AS $function$
DECLARE
v_new_insurer_pfr_name varchar(500) = null;
v_new_insurer_inn varchar(100) = null;
v_new_insurer_fund_id int = null::int;
begin
--поиск в документах ЕРЗЛ. исходим из того, что связка номер и дата договора в ЕРЗЛах уникальна
select su.new_insurer_pfr_name, su.new_insurer_inn, f.id fund_id, 'ЕРЗЛ'::varchar(255)
into v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id
from report.smev_uier su
join ourpension.fund f on f.inn = su.previos_insurer_inn
join ourpension.contract c on su.contract_number = c.number and su.contract_date = c.date
where su.uier_document_type_id in (2, 3) and c.id = ops_get_contract_new_insurer.contract_id; --2 - Возврат в CФР, 3 - Переход из НПФ в другие НПФ
if not (v_new_insurer_pfr_name is null or v_new_insurer_inn is null or v_new_insurer_fund_id is null) then
return query
select v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id, 'ЕРЗЛ'::varchar(255);
else
--поиск по решениям суда
select f.name_in_pfr, f.inn, f.id
into v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id
from ourpension.court_decision_data cdd
join ourpension.court_decision cd on cd.id = cdd.court_decision_id
join ourpension.fund f on f.id = cd.proper_insurer_id
where cdd.contract_id = ops_get_contract_new_insurer.contract_id
--and f.id <> ( select main_fund_id from tools.settings limit 1)
;
if not (v_new_insurer_pfr_name is null or v_new_insurer_inn is null or v_new_insurer_fund_id is null) then
return query
select v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id, 'Решение суда'::varchar(255);
else
--поиск Выплата трансферта (ОПС) в другой НПФ
select f.name_in_pfr, f.inn, f.id
into v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id
from ourpension.sharer s
join back_office."account" a on a.owner_sharer_id = s.id
join back_office.account_type at on a.account_type_id = at.id and at.mnemonics = 'В Т ОПС'
join back_office.transaction t on t.debit_account_id = a.id
join back_office.outgoing_order_operation ooo on ooo.operation_id = t.operation_id
join back_office.outgoing_order oo on oo.id = ooo.outgoing_order_id
join ourpension.fund f on f.entity_id = oo.recipient_entity_id
where s.contract_id = ops_get_contract_new_insurer.contract_id
order by oo.date asc
limit 1;
if not (v_new_insurer_pfr_name is null or v_new_insurer_inn is null or v_new_insurer_fund_id is null) then
return query
select v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id, 'Выплата трансферта (ОПС)'::varchar(255);
else
return query
select v_new_insurer_pfr_name, v_new_insurer_inn, v_new_insurer_fund_id, 'Не определен'::varchar(255);
end if;
end if;
end if;
end
$function$
;