Загрузка данных
-- DROP FUNCTION actuary.get_pension_scheme(_int4, _int4, date, text);
CREATE OR REPLACE FUNCTION actuary.get_pension_scheme(p_sharer_ids integer[], p_contract_ids integer[], p_calc_date date, p_service_type text)
RETURNS TABLE(prod_line_pens_scheme_id bigint, sharer_id integer, contract_id integer, number text, name text, investment_portfolio_name text, min_pension_value numeric, min_deposit_value numeric, inheritance_on_pay text, inheritance_on_accum text, oud numeric, duration_max integer, duration_min integer, mgd_accum numeric, mgd_pay numeric)
LANGUAGE plpgsql
AS $function$
declare
v_calc_datetime timestamp;
begin
v_calc_datetime = p_calc_date::timestamp + interval '23 hours 59 minutes';
return query
with base as (
select
s.id as sharer_id,
c.id as contract_id,
case
when p_contract_ids is null and sharer_product.id is not null then sharer_product.id
else contract_product.id
end as product_id
from ourpension.contract c
left join ourpension.sharer s on s.contract_id = c.id
left join lateral (
select distinct on (sph.sharer_id)
sph.pens_product_id as id
from ourpension.sharer_product_history sph
where sph.sharer_id = s.id
and sph.begin_date < v_calc_datetime
and (sph.end_date is null or sph.end_date > v_calc_datetime)
order by sph.sharer_id, sph.begin_date desc
) sharer_product on true
left join lateral (
select distinct on (cph.contract_id)
cph.pens_product_id as id
from ourpension.contract_product_history cph
where cph.contract_id = c.id
and cph.begin_date < v_calc_datetime
and (cph.end_date is null or cph.end_date > v_calc_datetime)
order by cph.contract_id, cph.begin_date desc
) contract_product on true
where (s.id = any(p_sharer_ids)) --or (c.id = any(p_contract_ids))
and (p_service_type is null or c.service_type = p_service_type)
)
select --distinct on (b.sharer_id)
ps.id as prod_line_pens_scheme_id, --ИД для фильтров в платформе
b.sharer_id::integer, --Номер счета, если выходим для участника
b.contract_id::integer, --Номер договора, если для вкладчика
ps.name::text as "number", --Имя пенс схемы для старого поля "Номер"
ps.brief::text as "name", --Имя пенс схемы
null::text as investment_portfolio_name, --Не найдено название(атрибут)
min_pens.value::numeric as min_pension_value, --Мин. размер пенсии
min_inpay.value_decimal::numeric as min_deposit_value, --Мин. размер взноса
inher.on_pay::text as inheritance_on_pay, --Наследование в период накопления
inher.on_accum::text as inheritance_on_accum, --Наследование в период выплат
oud.value::numeric as oud, --админ. взнос в фонд
duration.maximum::integer as duration_max, --Минимальный срок выплат
duration.minimum::integer as duration_min, --Максимальный срок выплат
mgd_accum.value_decimal::numeric as mgd_accum, --МГД в период накопления
mgd_pay.value_decimal::numeric as mgd_pay --МГД в период накопит
from base b
join prod_line.pens_product pp on pp.id = b.product_id
join prod_line.pens_scheme ps on ps.id = pp.pens_scheme_accum_stage_id
left join lateral(
select
pppl.value_decimal
from prod_line.pens_product_param_pl pppl
join prod_line.param_pl pl on pl.id = pppl.param_pl_id
where pppl.pens_product_id = pp.id
and pl.brief = 'МГДНакПериодС'
--limit 1
) mgd_accum on true
left join lateral(
select
pppl.value_decimal
from prod_line.pens_product_param_pl pppl
join prod_line.param_pl pl on pl.id = pppl.param_pl_id
where pppl.pens_product_id = pp.id
and pl.brief = 'МГДВыпПериодС'
--limit 1
) mgd_pay on true
left join lateral(
select
coalesce(tpppt.min_term_from, tpppt.min_term_to) as minimum,
coalesce(tpppt.max_term_to, tpppt.max_term_from) as maximum
from prod_line.pens_product_param_pl pppl
join prod_line.param_pl pl on pl.id = pppl.param_pl_id
join prod_line.table_param_pl_payment_term tpppt on tpppt.pens_product_param_pl_id = pppl.id
where pppl.pens_product_id = pp.id
and pl.brief = 'СрокВыплаты'
--limit 1
) duration on true
left join lateral(
select
case
when hppm.brief = 'НеПредусмотрено' or hppm.brief is null
then 'false'
when hppm.brief = 'ПредусмотрПериодНакоплИВыплат' or hppm.brief = 'ПредусмотрПериодНакопл'
then 'true'
end as on_accum,
case
when hppm.brief = 'НеПредусмотрено' or hppm.brief is null
then 'false'
when hppm.brief = 'ПредусмотрПериодНакоплИВыплат' or hppm.brief = 'ПредусмотрПериодВыплат'
then 'true'
end as on_pay
from prod_line.param_pl pl
join prod_line.pens_product_param_pl pppp on pppp.param_pl_id = pl.id
left join prod_line.pens_product_param_pl_hb_param_pl_multiselect pphm
on pphm.pens_product_param_pl_id = pppp.id
left join prod_line.hb_param_pl_multiselect hppm on hppm.id = pphm.hb_param_pl_multiselect_id
where pppp.pens_product_id = pp.id
and pl.brief = 'ПравопреемствоСмертьУчастника'
) inher on true
left join lateral(
select
coalesce(tppmp.min_pension_from, tppmp.min_pension_to) as value
from prod_line.pens_product_param_pl pppl
join prod_line.param_pl pl on pl.id = pppl.param_pl_id
join prod_line.table_param_pl_minimum_pension tppmp on tppmp.pens_product_param_pl_id = pppl.id
where pppl.pens_product_id = pp.id
and pl.brief = 'МинРазмерПенсии'
) min_pens on true
left join lateral(
select
case
when bool_or(
pppl.value_bool
) filter (
where pl.brief = 'ЕстьАдмВзнос'
) is true
then max(tppaf.amount_av) filter (
where pl.brief = 'АдмВзносВФонд'
)
else 0::numeric
end as value
from prod_line.pens_product_param_pl pppl
join prod_line.param_pl pl on pl.id = pppl.param_pl_id
left join prod_line.table_param_pl_administrative_fee tppaf
on tppaf.pens_product_param_pl_id = pppl.id
where pppl.pens_product_id = pp.id
and pl.brief in ('ЕстьАдмВзнос','АдмВзносВФонд'--,'ТипАдминВзноса','ВидАдминВзноса'
)
--limit 1
) oud on true
left join lateral(
select
coalesce(pppl.value_decimal, 0) as value_decimal
from prod_line.pens_product_param_pl pppl
join prod_line.param_pl pl on pl.id = pppl.param_pl_id
where pppl.pens_product_id = pp.id
and pl.brief in ('МинРазмерРегулВзносаС', 'МинРазмерРегулВзносаПо')
order by
case
when pl.brief = 'МинРазмерРегулВзносаС' then 1
when pl.brief = 'МинРазмерРегулВзносаПо' then 2
end
limit 1
) min_inpay on true;
end;
$function$
;