svod2-filter-fix: пофиксил фильтр по наличию записи в contract-detail в своде 2 #193

Merged
tsygankoviva merged 1 commits from svod2-filter-fix into test 2026-10-21 11:37:11 +03:00
2 changed files with 650 additions and 0 deletions
Showing only changes of commit 07cdcc6ed4 - Show all commits

View File

@ -0,0 +1,15 @@
from sql_migration import run_sql_file_migration
revision = "0048"
down_revision = "0047"
branch_labels = None
depends_on = None
def upgrade() -> None:
run_sql_file_migration("0048_summary2_optional_contract.sql")
def downgrade() -> None:
pass

View File

@ -0,0 +1,635 @@
-- Include source lines even when no contract_detail record exists.
CREATE OR REPLACE FUNCTION v3.v_svod2_go(
p_year integer,
p_org_unit_ids integer[] DEFAULT NULL,
p_offset integer DEFAULT NULL,
p_limit integer DEFAULT NULL,
p_sort_by varchar DEFAULT 'org_name',
p_sort_direction varchar DEFAULT 'asc'
)
RETURNS TABLE(
source_form varchar, source_id integer, source_org_unit_id integer,
org_name varchar, smeta_type varchar,
source_line_id integer, sort_order bigint, data jsonb
)
LANGUAGE sql STABLE SET search_path TO 'v3', 'pg_catalog'
AS $function$
WITH empty_sections AS MATERIALIZED (
SELECT
(to_jsonb(jsonb_populate_record(NULL::v3.plan, '{}'::jsonb)) - 'line_id')
|| jsonb_build_object('plan_year', NULL) AS plan,
(to_jsonb(jsonb_populate_record(NULL::v3.sequestration, '{}'::jsonb))
- 'id' - 'line_id' - 'actor') || jsonb_build_object('adj_year', NULL) AS sequestration,
(to_jsonb(jsonb_populate_record(NULL::v3.reserve, '{}'::jsonb)) - 'line_id')
|| jsonb_build_object('amount_year', NULL) AS reserve,
jsonb_build_object(
'approved_q1', NULL, 'approved_q2', NULL,
'approved_q3', NULL, 'approved_q4', NULL,
'approved_year', NULL
) AS approved,
to_jsonb(jsonb_populate_record(NULL::v3.contract_summary, '{}'::jsonb)) - 'line_id' AS contract_summary,
to_jsonb(jsonb_populate_record(NULL::v3.allocation, '{}'::jsonb)) - 'line_id' AS allocation,
to_jsonb(jsonb_populate_record(NULL::v3.collegial_approval, '{}'::jsonb)) - 'line_id' AS collegial,
to_jsonb(jsonb_populate_record(NULL::v3.ckk, '{}'::jsonb)) - 'line_id' AS ckk,
to_jsonb(jsonb_populate_record(NULL::v3.contract_detail, '{}'::jsonb)) - 'line_id' AS contract_detail,
to_jsonb(jsonb_populate_record(NULL::v3.booking, '{}'::jsonb)) - 'id' - 'line_id' AS booking,
to_jsonb(jsonb_populate_record(NULL::v3.budget_line_quarter, '{}'::jsonb))
- 'line_id' - 'quarter' AS quarter
), eligible_lines AS (
SELECT
bl.id AS line_id,
bf.form_type_code,
bf.id AS form_id,
bf.org_unit_id,
ou.title AS org_name,
ei.section_code,
ei.item_id,
CASE ei.sheet WHEN 'AHR' THEN 'АХР' WHEN 'CAP' THEN 'КВ'
WHEN 'OPER' THEN 'Операц' END::varchar AS smeta_type
FROM v3.budget_form bf
JOIN v3.budget_line bl ON bl.budget_form_id = bf.id
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id
WHERE bf.year = p_year
AND bf.form_type_code IN ('FORM_1', 'FORM_4')
AND ei.sheet IN ('AHR', 'CAP', 'OPER')
AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = 0
OR bf.org_unit_id = ANY(p_org_unit_ids))
), numbered_lines AS (
SELECT el.*,
row_number() OVER (
ORDER BY
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
THEN el.org_name END ASC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
THEN el.org_name END DESC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
THEN el.item_id END ASC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
THEN el.item_id END DESC NULLS LAST,
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'asc'
THEN el.section_code END ASC NULLS LAST,
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'desc'
THEN el.section_code END DESC NULLS LAST,
el.form_type_code, el.form_id, el.line_id
) AS sort_order
FROM eligible_lines el
), page AS MATERIALIZED (
SELECT * FROM numbered_lines
ORDER BY sort_order
LIMIT p_limit OFFSET COALESCE(p_offset, 0)
), booking_data AS (
SELECT b.line_id,
jsonb_agg(to_jsonb(b) - 'id' - 'line_id' ORDER BY b.quarter, b.source) AS booking
FROM page pg
JOIN v3.booking b ON b.line_id = pg.line_id
GROUP BY b.line_id
)
SELECT
pg.form_type_code,
pg.form_id,
pg.org_unit_id,
pg.org_name,
pg.smeta_type,
pg.line_id,
pg.sort_order,
jsonb_build_object(
'line_id', bl.id,
'header', jsonb_build_object(
'section_code', ei.section_code, 'item_id', ei.item_id,
'num_group', ei.num_group_id, 'name', COALESCE(bl.name, ei.name),
'expense_item_id', ei.id, 'justification', bl.justification,
'internal_order', bl.internal_order, 'vsp_id', bl.vsp_id,
'project_id', bl.project_id, 'direction', bl.direction,
'smeta_direction', CASE bl.direction
WHEN 'Support' THEN 'Поддержка'
WHEN 'Development' THEN 'Развитие'
ELSE NULL
END,
'source_form', pg.form_type_code, 'source_id', pg.form_id,
'source_org_unit_id', pg.org_unit_id, 'org_name', pg.org_name,
'smeta_type', pg.smeta_type),
'plan', COALESCE(
(to_jsonb(pl) - 'line_id') || jsonb_build_object(
'plan_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)),
e.plan || jsonb_build_object('plan_year', NULL)),
'sequestration', jsonb_build_object(
'DFIP', COALESCE(
(to_jsonb(sd) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
'adj_year', COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)),
e.sequestration || jsonb_build_object('adj_year', NULL)),
'SSP_GO', COALESCE(
(to_jsonb(ss) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
'adj_year', COALESCE(ss.adj_q1, 0) + COALESCE(ss.adj_q2, 0)
+ COALESCE(ss.adj_q3, 0) + COALESCE(ss.adj_q4, 0)),
e.sequestration || jsonb_build_object('adj_year', NULL))),
'reserve', COALESCE(
(to_jsonb(rv) - 'line_id') || jsonb_build_object(
'amount_year', COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)),
e.reserve || jsonb_build_object('amount_year', NULL)),
'approved', CASE WHEN pl.line_id IS NULL AND sd.id IS NULL
AND rv.line_id IS NULL
THEN e.approved
ELSE jsonb_build_object(
'approved_q1', COALESCE(pl.plan_q1, 0) + COALESCE(sd.adj_q1, 0)
+ COALESCE(rv.amount_q1, 0),
'approved_q2', COALESCE(pl.plan_q2, 0) + COALESCE(sd.adj_q2, 0)
+ COALESCE(rv.amount_q2, 0),
'approved_q3', COALESCE(pl.plan_q3, 0) + COALESCE(sd.adj_q3, 0)
+ COALESCE(rv.amount_q3, 0),
'approved_q4', COALESCE(pl.plan_q4, 0) + COALESCE(sd.adj_q4, 0)
+ COALESCE(rv.amount_q4, 0),
'approved_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)
+ COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)
+ COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)) END,
'contract_summary', COALESCE(to_jsonb(cs) - 'line_id', e.contract_summary),
'allocation', COALESCE(to_jsonb(al) - 'line_id', e.allocation),
'collegial', COALESCE(to_jsonb(ca) - 'line_id', e.collegial),
'ckk', COALESCE(to_jsonb(ck) - 'line_id', e.ckk),
'contract_detail', COALESCE(to_jsonb(cd) - 'line_id', e.contract_detail),
'booking', COALESCE(bk.booking, jsonb_build_array(e.booking)),
'q1', COALESCE(to_jsonb(q1) - 'line_id' - 'quarter', e.quarter) || jsonb_build_object(
'booking_amount', CASE WHEN pg.form_type_code = 'FORM_1'
THEN CASE WHEN COALESCE(cd.expenses_q1, 0) > 0 THEN cd.expenses_q1 ELSE ck.expenses_q1 END
ELSE COALESCE(q1.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q1
WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1
ELSE cd.expenses_q1 END) END),
'q2', COALESCE(to_jsonb(q2) - 'line_id' - 'quarter', e.quarter) || jsonb_build_object(
'booking_amount', CASE WHEN pg.form_type_code = 'FORM_1'
THEN CASE WHEN COALESCE(cd.expenses_q2, 0) > 0 THEN cd.expenses_q2 ELSE ck.expenses_q2 END
ELSE COALESCE(q2.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q2
WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2
ELSE cd.expenses_q2 END) END,
'plan_revision_eco_change', COALESCE(q2.target_change, q2.plan_revision_eco_change),
'plan_revision_item_adj', COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),
'q3', COALESCE(to_jsonb(q3) - 'line_id' - 'quarter', e.quarter) || jsonb_build_object(
'booking_amount', CASE WHEN pg.form_type_code = 'FORM_1'
THEN CASE WHEN COALESCE(cd.expenses_q3, 0) > 0 THEN cd.expenses_q3 ELSE ck.expenses_q3 END
ELSE COALESCE(q3.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q3
WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3
ELSE cd.expenses_q3 END) END,
'plan_revision_eco_change', COALESCE(q3.target_change, q3.plan_revision_eco_change),
'plan_revision_item_adj', COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),
'q4', COALESCE(to_jsonb(q4) - 'line_id' - 'quarter', e.quarter) || jsonb_build_object(
'booking_amount', CASE WHEN pg.form_type_code = 'FORM_1'
THEN CASE WHEN COALESCE(cd.expenses_q4, 0) > 0 THEN cd.expenses_q4 ELSE ck.expenses_q4 END
ELSE COALESCE(q4.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q4
WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4
ELSE cd.expenses_q4 END) END,
'plan_revision_eco_change', COALESCE(q4.target_change, q4.plan_revision_eco_change),
'plan_revision_item_adj', COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))
) AS data
FROM page pg
JOIN v3.budget_line bl ON bl.id = pg.line_id
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id
CROSS JOIN empty_sections e
LEFT JOIN v3.plan pl ON pl.line_id = bl.id
LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP'
LEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = 'SSP_GO'
LEFT JOIN v3.reserve rv ON rv.line_id = bl.id
LEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id
LEFT JOIN v3.allocation al ON al.line_id = bl.id
LEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id
LEFT JOIN v3.ckk ck ON ck.line_id = bl.id
LEFT JOIN booking_data bk ON bk.line_id = bl.id
LEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = 1
LEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = 2
LEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = 3
LEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = 4
ORDER BY pg.sort_order;
$function$;
CREATE OR REPLACE FUNCTION v3.v_svod2_rf(
p_year integer,
p_org_unit_ids integer[] DEFAULT NULL,
p_offset integer DEFAULT NULL,
p_limit integer DEFAULT NULL,
p_sort_by varchar DEFAULT 'org_name',
p_sort_direction varchar DEFAULT 'asc'
)
RETURNS TABLE(
source_form varchar, source_id integer, source_org_unit_id integer,
org_name varchar, smeta_type varchar,
source_line_id integer, sort_order bigint, data jsonb
)
LANGUAGE sql STABLE SET search_path TO 'v3', 'pg_catalog'
AS $function$
WITH empty_sections AS MATERIALIZED (
SELECT
(to_jsonb(jsonb_populate_record(NULL::v3.plan, '{}'::jsonb)) - 'line_id')
|| jsonb_build_object('plan_year', NULL) AS plan,
(to_jsonb(jsonb_populate_record(NULL::v3.sequestration, '{}'::jsonb))
- 'id' - 'line_id' - 'actor') || jsonb_build_object('adj_year', NULL) AS sequestration,
(to_jsonb(jsonb_populate_record(NULL::v3.reserve, '{}'::jsonb)) - 'line_id')
|| jsonb_build_object('amount_year', NULL) AS reserve,
jsonb_build_object(
'approved_q1', NULL, 'approved_q2', NULL,
'approved_q3', NULL, 'approved_q4', NULL,
'approved_year', NULL
) AS approved,
to_jsonb(jsonb_populate_record(NULL::v3.contract_summary, '{}'::jsonb)) - 'line_id' AS contract_summary,
to_jsonb(jsonb_populate_record(NULL::v3.allocation, '{}'::jsonb)) - 'line_id' AS allocation,
to_jsonb(jsonb_populate_record(NULL::v3.collegial_approval, '{}'::jsonb)) - 'line_id' AS collegial,
to_jsonb(jsonb_populate_record(NULL::v3.ckk, '{}'::jsonb)) - 'line_id' AS ckk,
to_jsonb(jsonb_populate_record(NULL::v3.contract_detail, '{}'::jsonb)) - 'line_id' AS contract_detail,
to_jsonb(jsonb_populate_record(NULL::v3.booking, '{}'::jsonb)) - 'id' - 'line_id' AS booking,
to_jsonb(jsonb_populate_record(NULL::v3.budget_line_quarter, '{}'::jsonb))
- 'line_id' - 'quarter' AS budget_quarter
), eligible_lines AS (
SELECT
'FORM_2'::varchar AS form_type_code,
bl.id AS line_id,
bf.id AS source_id,
bf.org_unit_id,
ou.title AS org_name,
ei.section_code,
ei.item_id,
CASE ei.sheet WHEN 'AHR' THEN 'АХР' WHEN 'CAP' THEN 'КВ'
WHEN 'OPER' THEN 'Операц' END::varchar AS smeta_type
FROM v3.budget_form bf
JOIN v3.budget_line bl ON bl.budget_form_id = bf.id
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id
WHERE bf.year = p_year AND bf.form_type_code = 'FORM_2'
AND ei.sheet IN ('AHR', 'CAP', 'OPER')
AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = 0
OR bf.org_unit_id = ANY(p_org_unit_ids))
), numbered_lines AS (
SELECT el.*,
row_number() OVER (
ORDER BY
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
THEN el.org_name END ASC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
THEN el.org_name END DESC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
THEN el.item_id END ASC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
THEN el.item_id END DESC NULLS LAST,
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'asc'
THEN el.section_code END ASC NULLS LAST,
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'desc'
THEN el.section_code END DESC NULLS LAST,
el.form_type_code, el.source_id, el.line_id
) AS sort_order
FROM eligible_lines el
), page AS MATERIALIZED (
SELECT * FROM numbered_lines
ORDER BY sort_order
LIMIT p_limit OFFSET COALESCE(p_offset, 0)
), booking_data AS (
SELECT b.line_id,
jsonb_agg(to_jsonb(b) - 'id' - 'line_id' ORDER BY b.quarter, b.source) AS booking
FROM page pg
JOIN v3.booking b ON b.line_id = pg.line_id
GROUP BY b.line_id
)
SELECT
pg.form_type_code AS source_form, pg.source_id,
pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,
pg.line_id AS source_line_id, pg.sort_order,
jsonb_build_object(
'line_id', bl.id,
'header', jsonb_build_object(
'section_code', ei.section_code, 'item_id', ei.item_id,
'num_group', ei.num_group_id, 'name', COALESCE(bl.name, ei.name),
'expense_item_id', ei.id, 'justification', bl.justification,
'internal_order', bl.internal_order, 'vsp_id', bl.vsp_id,
'project_id', bl.project_id, 'direction', bl.direction,
'smeta_direction', CASE bl.direction
WHEN 'Support' THEN 'Поддержка'
WHEN 'Development' THEN 'Развитие'
ELSE NULL
END,
'source_form', pg.form_type_code, 'source_id', pg.source_id,
'source_org_unit_id', pg.org_unit_id, 'org_name', pg.org_name,
'smeta_type', pg.smeta_type),
'plan', COALESCE(
(to_jsonb(pl) - 'line_id') || jsonb_build_object(
'plan_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)),
e.plan || jsonb_build_object('plan_year', NULL)),
'sequestration', jsonb_build_object(
'DFIP', COALESCE(
(to_jsonb(sd) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
'adj_year', COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)),
e.sequestration || jsonb_build_object('adj_year', NULL)),
'SSP_GO', COALESCE(
(to_jsonb(ss) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
'adj_year', COALESCE(ss.adj_q1, 0) + COALESCE(ss.adj_q2, 0)
+ COALESCE(ss.adj_q3, 0) + COALESCE(ss.adj_q4, 0)),
e.sequestration || jsonb_build_object('adj_year', NULL))),
'reserve', COALESCE(
(to_jsonb(rv) - 'line_id') || jsonb_build_object(
'amount_year', COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)),
e.reserve || jsonb_build_object('amount_year', NULL)),
'approved', CASE WHEN pl.line_id IS NULL AND sd.id IS NULL
AND ss.id IS NULL AND rv.line_id IS NULL
THEN e.approved
ELSE jsonb_build_object(
'approved_q1', COALESCE(pl.plan_q1, 0) + COALESCE(sd.adj_q1, 0)
+ COALESCE(ss.adj_q1, 0) + COALESCE(rv.amount_q1, 0),
'approved_q2', COALESCE(pl.plan_q2, 0) + COALESCE(sd.adj_q2, 0)
+ COALESCE(ss.adj_q2, 0) + COALESCE(rv.amount_q2, 0),
'approved_q3', COALESCE(pl.plan_q3, 0) + COALESCE(sd.adj_q3, 0)
+ COALESCE(ss.adj_q3, 0) + COALESCE(rv.amount_q3, 0),
'approved_q4', COALESCE(pl.plan_q4, 0) + COALESCE(sd.adj_q4, 0)
+ COALESCE(ss.adj_q4, 0) + COALESCE(rv.amount_q4, 0),
'approved_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)
+ COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)
+ COALESCE(ss.adj_q1, 0) + COALESCE(ss.adj_q2, 0)
+ COALESCE(ss.adj_q3, 0) + COALESCE(ss.adj_q4, 0)
+ COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)) END,
'contract_summary', COALESCE(to_jsonb(cs) - 'line_id', e.contract_summary),
'allocation', COALESCE(to_jsonb(al) - 'line_id', e.allocation),
'collegial', COALESCE(to_jsonb(ca) - 'line_id', e.collegial),
'ckk', COALESCE(to_jsonb(ck) - 'line_id', e.ckk),
'contract_detail', COALESCE(to_jsonb(cd) - 'line_id', e.contract_detail) || jsonb_build_object(
'expenses_q1', COALESCE(cd.expenses_q1, ck.expenses_q1),
'expenses_q2', COALESCE(cd.expenses_q2, ck.expenses_q2),
'expenses_q3', COALESCE(cd.expenses_q3, ck.expenses_q3),
'expenses_q4', COALESCE(cd.expenses_q4, ck.expenses_q4)),
'booking', COALESCE(bk.booking, jsonb_build_array(e.booking)),
'q1', COALESCE(to_jsonb(q1) - 'line_id' - 'quarter', e.budget_quarter) || jsonb_build_object(
'booking_amount', COALESCE(q1.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q1
WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1
ELSE cd.expenses_q1 END)),
'q2', COALESCE(to_jsonb(q2) - 'line_id' - 'quarter', e.budget_quarter) || jsonb_build_object(
'booking_amount', COALESCE(q2.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q2
WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2
ELSE cd.expenses_q2 END),
'plan_revision_eco_change', COALESCE(q2.target_change, q2.plan_revision_eco_change),
'plan_revision_item_adj', COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)),
'q3', COALESCE(to_jsonb(q3) - 'line_id' - 'quarter', e.budget_quarter) || jsonb_build_object(
'booking_amount', COALESCE(q3.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q3
WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3
ELSE cd.expenses_q3 END),
'plan_revision_eco_change', COALESCE(q3.target_change, q3.plan_revision_eco_change),
'plan_revision_item_adj', COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)),
'q4', COALESCE(to_jsonb(q4) - 'line_id' - 'quarter', e.budget_quarter) || jsonb_build_object(
'booking_amount', COALESCE(q4.booking_amount,
CASE WHEN ei.sheet = 'AHR' THEN ck.expenses_q4
WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4
ELSE cd.expenses_q4 END),
'plan_revision_eco_change', COALESCE(q4.target_change, q4.plan_revision_eco_change),
'plan_revision_item_adj', COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj))
) AS data
FROM page pg
JOIN v3.budget_line bl ON bl.id = pg.line_id
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id
CROSS JOIN empty_sections e
LEFT JOIN v3.plan pl ON pl.line_id = bl.id
LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP'
LEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = 'SSP_GO'
LEFT JOIN v3.reserve rv ON rv.line_id = bl.id
LEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id
LEFT JOIN v3.allocation al ON al.line_id = bl.id
LEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id
LEFT JOIN v3.ckk ck ON ck.line_id = bl.id
LEFT JOIN booking_data bk ON bk.line_id = bl.id
LEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = 1
LEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = 2
LEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = 3
LEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = 4
ORDER BY pg.sort_order;
$function$;
CREATE OR REPLACE FUNCTION v3.v_svod2_go_export(
p_year integer,
p_org_unit_ids integer[] DEFAULT NULL,
p_sort_by varchar DEFAULT 'org_name',
p_sort_direction varchar DEFAULT 'asc'
)
RETURNS TABLE(sort_order bigint, row_values text[])
LANGUAGE sql
STABLE
SET search_path TO 'v3', 'pg_catalog'
AS $function$
WITH eligible_lines AS (
SELECT
bl.id AS line_id,
bf.form_type_code,
bf.id AS form_id,
bf.org_unit_id,
ou.title AS org_name,
ei.section_code,
ei.item_id,
ei.num_group_id,
COALESCE(bl.name, ei.name) AS name,
bl.justification,
CASE bl.direction
WHEN 'Support' THEN 'Поддержка'
WHEN 'Development' THEN 'Развитие'
END::varchar AS smeta_direction,
CASE ei.sheet
WHEN 'AHR' THEN 'АХР'
WHEN 'CAP' THEN 'КВ'
WHEN 'OPER' THEN 'Операц'
END::varchar AS smeta_type,
ei.sheet,
cd.counterparty,
cd.reference,
cd.subject,
cd.currency,
cd.ceiling_amount,
cd.expenses_q1,
cd.expenses_q2,
cd.expenses_q3,
cd.expenses_q4,
cd.vat_rate,
cd.deadline
FROM v3.budget_form bf
JOIN v3.budget_line bl ON bl.budget_form_id = bf.id
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id
LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id
WHERE bf.year = p_year
AND bf.form_type_code IN ('FORM_1', 'FORM_4')
AND ei.sheet IN ('AHR', 'CAP', 'OPER')
AND (
p_org_unit_ids IS NULL
OR cardinality(p_org_unit_ids) = 0
OR bf.org_unit_id = ANY(p_org_unit_ids)
)
), page AS MATERIALIZED (
SELECT
el.*,
row_number() OVER (
ORDER BY
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc' THEN el.org_name END ASC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc' THEN el.org_name END DESC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc' THEN el.item_id END ASC NULLS LAST,
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc' THEN el.item_id END DESC NULLS LAST,
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'asc' THEN el.section_code END ASC NULLS LAST,
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'desc' THEN el.section_code END DESC NULLS LAST,
el.form_type_code,
el.form_id,
el.line_id
) AS sort_order
FROM eligible_lines el
)
SELECT
pg.sort_order,
ARRAY[
pg.smeta_type::text,
pg.smeta_direction::text,
pg.org_name::text,
pg.name::text,
pg.item_id::text,
pg.num_group_id::text,
pg.justification::text,
pl.plan_q1::text,
pl.plan_q2::text,
pl.plan_q3::text,
pl.plan_q4::text,
al.internal_order::text,
al.property_object::text,
sd.adj_q1::text,
sd.adj_q2::text,
sd.adj_q3::text,
sd.adj_q4::text,
rv.amount_q1::text,
rv.amount_q2::text,
rv.amount_q3::text,
rv.amount_q4::text,
(CASE WHEN pl.line_id IS NULL AND sd.id IS NULL AND rv.line_id IS NULL THEN NULL ELSE COALESCE(pl.plan_q1, 0) + COALESCE(sd.adj_q1, 0) + COALESCE(rv.amount_q1, 0) END)::text,
(CASE WHEN pl.line_id IS NULL AND sd.id IS NULL AND rv.line_id IS NULL THEN NULL ELSE COALESCE(pl.plan_q2, 0) + COALESCE(sd.adj_q2, 0) + COALESCE(rv.amount_q2, 0) END)::text,
(CASE WHEN pl.line_id IS NULL AND sd.id IS NULL AND rv.line_id IS NULL THEN NULL ELSE COALESCE(pl.plan_q3, 0) + COALESCE(sd.adj_q3, 0) + COALESCE(rv.amount_q3, 0) END)::text,
(CASE WHEN pl.line_id IS NULL AND sd.id IS NULL AND rv.line_id IS NULL THEN NULL ELSE COALESCE(pl.plan_q4, 0) + COALESCE(sd.adj_q4, 0) + COALESCE(rv.amount_q4, 0) END)::text,
pg.counterparty::text,
pg.reference::text,
pg.subject::text,
pg.currency::text,
pg.ceiling_amount::text,
pg.expenses_q1::text,
pg.expenses_q2::text,
pg.expenses_q3::text,
pg.expenses_q4::text,
pg.vat_rate::text,
pg.deadline::text,
q1.adj_current::text,
q1.adj_ssp::text,
q1.adj_rf::text,
q1.adj_reserve::text,
q1.payment_date::text,
q1.payment_amount::text,
q1.payment_amount_ho::text,
q1.payment_amount_rf::text,
q1.payment_act::text,
(CASE WHEN pg.form_type_code = 'FORM_1' THEN CASE WHEN COALESCE(cd.expenses_q1, 0) > 0 THEN cd.expenses_q1 ELSE ck.expenses_q1 END ELSE COALESCE(q1.booking_amount,
CASE WHEN pg.sheet = 'AHR' THEN ck.expenses_q1
WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1
ELSE cd.expenses_q1 END) END)::text,
q1.actual_m1::text,
q1.actual_m2::text,
q1.actual_m3::text,
q1.transfer_to_q2::text,
q1.transfer_to_q3::text,
q1.transfer_to_q4::text,
q1.transfer_to_economy::text,
q2.adj_current::text,
q2.adj_ssp::text,
q2.adj_rf::text,
q2.adj_reserve::text,
q2.payment_date::text,
q2.payment_amount::text,
q2.payment_amount_ho::text,
q2.payment_amount_rf::text,
q2.payment_act::text,
(CASE WHEN pg.form_type_code = 'FORM_1' THEN CASE WHEN COALESCE(cd.expenses_q2, 0) > 0 THEN cd.expenses_q2 ELSE ck.expenses_q2 END ELSE COALESCE(q2.booking_amount,
CASE WHEN pg.sheet = 'AHR' THEN ck.expenses_q2
WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2
ELSE cd.expenses_q2 END) END)::text,
q2.actual_m1::text,
q2.actual_m2::text,
q2.actual_m3::text,
COALESCE(q2.target_change, q2.plan_revision_eco_change)::text,
COALESCE(q2.base_plan_correction, q2.plan_revision_item_adj)::text,
q2.plan_revision_increase::text,
q2.plan_revision_sequester::text,
q2.transfer_to_q3::text,
q2.transfer_to_q4::text,
q2.transfer_to_economy::text,
q3.adj_current::text,
q3.adj_ssp::text,
q3.adj_rf::text,
q3.adj_reserve::text,
q3.payment_date::text,
q3.payment_amount::text,
q3.payment_amount_ho::text,
q3.payment_amount_rf::text,
q3.payment_act::text,
(CASE WHEN pg.form_type_code = 'FORM_1' THEN CASE WHEN COALESCE(cd.expenses_q3, 0) > 0 THEN cd.expenses_q3 ELSE ck.expenses_q3 END ELSE COALESCE(q3.booking_amount,
CASE WHEN pg.sheet = 'AHR' THEN ck.expenses_q3
WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3
ELSE cd.expenses_q3 END) END)::text,
q3.actual_m1::text,
q3.actual_m2::text,
q3.actual_m3::text,
COALESCE(q3.target_change, q3.plan_revision_eco_change)::text,
COALESCE(q3.base_plan_correction, q3.plan_revision_item_adj)::text,
q3.plan_revision_increase::text,
q3.plan_revision_sequester::text,
q3.transfer_to_q4::text,
q3.transfer_to_economy::text,
q4.adj_current::text,
q4.adj_ssp::text,
q4.adj_rf::text,
q4.adj_reserve::text,
q4.payment_date::text,
q4.payment_amount::text,
q4.payment_amount_ho::text,
q4.payment_amount_rf::text,
q4.payment_act::text,
(CASE WHEN pg.form_type_code = 'FORM_1' THEN CASE WHEN COALESCE(cd.expenses_q4, 0) > 0 THEN cd.expenses_q4 ELSE ck.expenses_q4 END ELSE COALESCE(q4.booking_amount,
CASE WHEN pg.sheet = 'AHR' THEN ck.expenses_q4
WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4
ELSE cd.expenses_q4 END) END)::text,
q4.actual_m1::text,
q4.actual_m2::text,
q4.actual_m3::text,
q4.actual_spod::text,
COALESCE(q4.target_change, q4.plan_revision_eco_change)::text,
COALESCE(q4.base_plan_correction, q4.plan_revision_item_adj)::text,
q4.plan_revision_increase::text,
q4.plan_revision_sequester::text
]::text[] AS row_values
FROM page pg
LEFT JOIN v3.contract_detail cd ON cd.line_id = pg.line_id
LEFT JOIN v3.ckk ck ON ck.line_id = pg.line_id
LEFT JOIN v3.plan pl ON pl.line_id = pg.line_id
LEFT JOIN v3.sequestration sd
ON sd.line_id = pg.line_id
AND sd.actor = 'DFIP'
LEFT JOIN v3.reserve rv ON rv.line_id = pg.line_id
LEFT JOIN v3.allocation al ON al.line_id = pg.line_id
LEFT JOIN v3.budget_line_quarter q1
ON q1.line_id = pg.line_id AND q1.quarter = 1
LEFT JOIN v3.budget_line_quarter q2
ON q2.line_id = pg.line_id AND q2.quarter = 2
LEFT JOIN v3.budget_line_quarter q3
ON q3.line_id = pg.line_id AND q3.quarter = 3
LEFT JOIN v3.budget_line_quarter q4
ON q4.line_id = pg.line_id AND q4.quarter = 4
ORDER BY pg.sort_order;
$function$;