From 155ab65b58f337c68763378bcfd39fb487fd7e38 Mon Sep 17 00:00:00 2001 From: tsygankoviva Date: Tue, 3 Nov 2026 13:08:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BB=D0=B8=D0=BB=20=D0=B4=D1=83=D0=B1?= =?UTF-8?q?=D0=BB=D0=B8=D1=80=D1=83=D0=B1=D1=89=D0=B8=D0=B5=20=D0=BD=D0=BE?= =?UTF-8?q?=D0=BC=D0=B5=D1=80=D0=B0=20=D0=BC=D0=B8=D0=B3=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0050_project_technical_number_lock.py | 15 - .../versions/0051_upd_form_cells_full_rows.py | 15 - .../versions/0052_upd_form_cells_subtree.py | 15 - api/alembic/versions/0053_form4_sheet_sum.py | 15 - .../sql/0050_form2_ahr_spod_column.sql | 98 + .../0050_project_technical_number_lock.sql | 96 - .../sql/0051_form2_ahr_satellite_new_line.sql | 197 ++ .../sql/0051_upd_form_cells_full_rows.sql | 194 -- .../0052_form2_ahr_limit_period_vat_units.sql | 2795 ++++++++++++++++- .../sql/0052_upd_form_cells_subtree.sql | 2791 ---------------- .../sql/0053_form2_ahr_source_sheet.sql | 606 ++++ .../versions/sql/0053_form4_sheet_sum.sql | 603 ---- 12 files changed, 3695 insertions(+), 3745 deletions(-) delete mode 100644 api/alembic/versions/0050_project_technical_number_lock.py delete mode 100644 api/alembic/versions/0051_upd_form_cells_full_rows.py delete mode 100644 api/alembic/versions/0052_upd_form_cells_subtree.py delete mode 100644 api/alembic/versions/0053_form4_sheet_sum.py delete mode 100644 api/alembic/versions/sql/0050_project_technical_number_lock.sql delete mode 100644 api/alembic/versions/sql/0051_upd_form_cells_full_rows.sql delete mode 100644 api/alembic/versions/sql/0052_upd_form_cells_subtree.sql delete mode 100644 api/alembic/versions/sql/0053_form4_sheet_sum.sql diff --git a/api/alembic/versions/0050_project_technical_number_lock.py b/api/alembic/versions/0050_project_technical_number_lock.py deleted file mode 100644 index d93500a..0000000 --- a/api/alembic/versions/0050_project_technical_number_lock.py +++ /dev/null @@ -1,15 +0,0 @@ -from sql_migration import run_sql_file_migration - - -revision = "0050" -down_revision = "0049" -branch_labels = None -depends_on = None - - -def upgrade() -> None: - run_sql_file_migration("0050_project_technical_number_lock.sql") - - -def downgrade() -> None: - pass diff --git a/api/alembic/versions/0051_upd_form_cells_full_rows.py b/api/alembic/versions/0051_upd_form_cells_full_rows.py deleted file mode 100644 index 0ecd3bb..0000000 --- a/api/alembic/versions/0051_upd_form_cells_full_rows.py +++ /dev/null @@ -1,15 +0,0 @@ -from sql_migration import run_sql_file_migration - - -revision = "0051" -down_revision = "0050" -branch_labels = None -depends_on = None - - -def upgrade() -> None: - run_sql_file_migration("0051_upd_form_cells_full_rows.sql") - - -def downgrade() -> None: - pass diff --git a/api/alembic/versions/0052_upd_form_cells_subtree.py b/api/alembic/versions/0052_upd_form_cells_subtree.py deleted file mode 100644 index 830fd41..0000000 --- a/api/alembic/versions/0052_upd_form_cells_subtree.py +++ /dev/null @@ -1,15 +0,0 @@ -from sql_migration import run_sql_file_migration - - -revision = "0052" -down_revision = "0051" -branch_labels = None -depends_on = None - - -def upgrade() -> None: - run_sql_file_migration("0052_upd_form_cells_subtree.sql") - - -def downgrade() -> None: - pass diff --git a/api/alembic/versions/0053_form4_sheet_sum.py b/api/alembic/versions/0053_form4_sheet_sum.py deleted file mode 100644 index 46d04e0..0000000 --- a/api/alembic/versions/0053_form4_sheet_sum.py +++ /dev/null @@ -1,15 +0,0 @@ -from sql_migration import run_sql_file_migration - - -revision = "0053" -down_revision = "0052" -branch_labels = None -depends_on = None - - -def upgrade() -> None: - run_sql_file_migration("0053_form4_sheet_sum.sql") - - -def downgrade() -> None: - pass diff --git a/api/alembic/versions/sql/0050_form2_ahr_spod_column.sql b/api/alembic/versions/sql/0050_form2_ahr_spod_column.sql index f96f337..2427c62 100644 --- a/api/alembic/versions/sql/0050_form2_ahr_spod_column.sql +++ b/api/alembic/versions/sql/0050_form2_ahr_spod_column.sql @@ -1626,3 +1626,101 @@ UPDATE v3.form_phase WHERE sheet IN ('AHR_RENT', 'AHR_UTILITY', 'AHR_SECURITY') AND 'fact_q4.dec' = ANY(column_keys) AND NOT ('fact_q4.spod' = ANY(column_keys)); + + +-- AURORA-1831: гонка technical_number при параллельном создании проектов. +-- v3.add_project: копия версии из 0018 + advisory lock перед вычислением счётчика +-- и понятная ошибка при переполнении счётчика (больше 99 проектов на оргединицу). + +CREATE OR REPLACE FUNCTION v3.add_project(p_name character varying, p_year integer, p_org_unit_id integer, p_level character varying DEFAULT 'project'::character varying, p_parent_id integer DEFAULT NULL::integer, p_project_type character varying DEFAULT NULL::character varying, p_vsp_format character varying DEFAULT NULL::character varying, p_placement_type character varying DEFAULT NULL::character varying, p_object_address character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_system_code character varying DEFAULT NULL::character varying) + RETURNS TABLE(project_id integer, limit_report_id integer, current_expenses_report_id integer) + LANGUAGE plpgsql +AS $function$ +DECLARE + v_pid INT; + v_lim INT; + v_cur INT; + v_seq INT; + v_technical_number VARCHAR; +BEGIN + IF p_name IS NULL OR length(trim(p_name)) = 0 THEN + RAISE EXCEPTION 'p_name обязателен'; + END IF; + IF p_year IS NULL THEN + RAISE EXCEPTION 'p_year обязателен'; + END IF; + IF p_org_unit_id IS NULL THEN + RAISE EXCEPTION 'p_org_unit_id обязателен'; + END IF; + IF NOT EXISTS (SELECT 1 FROM v3.org_unit ou WHERE id = p_org_unit_id AND ou.is_active) THEN + RAISE EXCEPTION 'org_unit id=% не существует', p_org_unit_id; + END IF; + IF p_parent_id IS NOT NULL AND + NOT EXISTS (SELECT 1 FROM v3.project WHERE id = p_parent_id AND level = 'program') THEN + RAISE EXCEPTION 'parent project id=% не существует или не имеет level=program', p_parent_id; + END IF; + + -- AURORA-1831: сериализуем выдачу номера внутри одной оргединицы. Без блокировки + -- две параллельные транзакции читают один и тот же MAX и падают на уникальном индексе. + -- Блокировка снимается на COMMIT/ROLLBACK. Решение опирается на READ COMMITTED + -- (приложение не меняет изоляцию): после получения блокировки SELECT MAX берёт новый + -- снимок и видит строку, закоммиченную предыдущим владельцем. При REPEATABLE READ + -- и выше этого недостаточно. + PERFORM pg_advisory_xact_lock(hashtext('v3.project.technical_number'), p_org_unit_id); + + -- Порядковый счётчик проекта для данного РФ/ВСП (org_unit) + SELECT COALESCE(MAX(right(technical_number, 2)::int), 0) + 1 + INTO v_seq + FROM v3.project + WHERE org_unit_id = p_org_unit_id + AND technical_number IS NOT NULL; + + IF v_seq > 99 THEN + RAISE EXCEPTION 'Исчерпан счётчик технических номеров проектов для org_unit id=% (максимум 99)', p_org_unit_id; + END IF; + + v_technical_number := to_char(now(), 'YYMM') || '_' + || lpad(p_org_unit_id::text, 4, '0') + || lpad(v_seq::text, 2, '0'); + + INSERT INTO v3.project ( + name, level, parent_id, org_unit_id, + project_type, vsp_format, placement_type, object_address, staff_count, total_area, + system_code, technical_number + ) VALUES ( + p_name, p_level, p_parent_id, p_org_unit_id, + p_project_type, p_vsp_format, p_placement_type, p_object_address, p_staff_count, p_total_area, + p_system_code, v_technical_number + ) RETURNING id INTO v_pid; + + -- Первый год: 2 отчёта (LIMIT + CURRENT_EXPENSES) + snapshot фаз + сетка статей. + SELECT y.limit_report_id, y.current_expenses_report_id + INTO v_lim, v_cur + FROM v3.add_project_year(v_pid, p_year, false) y; + + -- Аудит: PROJECT_CREATE — все заполненные поля + id отчётов + PERFORM v3.log_event( + 'PROJECT_CREATE', 'PROJECT', + jsonb_strip_nulls(jsonb_build_object( + 'project_id', v_pid, + 'name', p_name, + 'year', p_year, + 'level', p_level, + 'parent_id', p_parent_id, + 'org_unit_id', p_org_unit_id, + 'project_type', p_project_type, + 'vsp_format', p_vsp_format, + 'placement_type', p_placement_type, + 'object_address', p_object_address, + 'system_code', p_system_code, + 'technical_number', v_technical_number, + 'staff_count', p_staff_count, + 'total_area', p_total_area, + 'limit_report_id', v_lim, + 'current_expenses_report_id', v_cur + )) + ); + + RETURN QUERY SELECT v_pid, v_lim, v_cur; +END; +$function$; diff --git a/api/alembic/versions/sql/0050_project_technical_number_lock.sql b/api/alembic/versions/sql/0050_project_technical_number_lock.sql deleted file mode 100644 index 7236be4..0000000 --- a/api/alembic/versions/sql/0050_project_technical_number_lock.sql +++ /dev/null @@ -1,96 +0,0 @@ --- AURORA-1831: гонка technical_number при параллельном создании проектов. --- v3.add_project: копия версии из 0018 + advisory lock перед вычислением счётчика --- и понятная ошибка при переполнении счётчика (больше 99 проектов на оргединицу). - -CREATE OR REPLACE FUNCTION v3.add_project(p_name character varying, p_year integer, p_org_unit_id integer, p_level character varying DEFAULT 'project'::character varying, p_parent_id integer DEFAULT NULL::integer, p_project_type character varying DEFAULT NULL::character varying, p_vsp_format character varying DEFAULT NULL::character varying, p_placement_type character varying DEFAULT NULL::character varying, p_object_address character varying DEFAULT NULL::character varying, p_staff_count integer DEFAULT NULL::integer, p_total_area numeric DEFAULT NULL::numeric, p_system_code character varying DEFAULT NULL::character varying) - RETURNS TABLE(project_id integer, limit_report_id integer, current_expenses_report_id integer) - LANGUAGE plpgsql -AS $function$ -DECLARE - v_pid INT; - v_lim INT; - v_cur INT; - v_seq INT; - v_technical_number VARCHAR; -BEGIN - IF p_name IS NULL OR length(trim(p_name)) = 0 THEN - RAISE EXCEPTION 'p_name обязателен'; - END IF; - IF p_year IS NULL THEN - RAISE EXCEPTION 'p_year обязателен'; - END IF; - IF p_org_unit_id IS NULL THEN - RAISE EXCEPTION 'p_org_unit_id обязателен'; - END IF; - IF NOT EXISTS (SELECT 1 FROM v3.org_unit ou WHERE id = p_org_unit_id AND ou.is_active) THEN - RAISE EXCEPTION 'org_unit id=% не существует', p_org_unit_id; - END IF; - IF p_parent_id IS NOT NULL AND - NOT EXISTS (SELECT 1 FROM v3.project WHERE id = p_parent_id AND level = 'program') THEN - RAISE EXCEPTION 'parent project id=% не существует или не имеет level=program', p_parent_id; - END IF; - - -- AURORA-1831: сериализуем выдачу номера внутри одной оргединицы. Без блокировки - -- две параллельные транзакции читают один и тот же MAX и падают на уникальном индексе. - -- Блокировка снимается на COMMIT/ROLLBACK. Решение опирается на READ COMMITTED - -- (приложение не меняет изоляцию): после получения блокировки SELECT MAX берёт новый - -- снимок и видит строку, закоммиченную предыдущим владельцем. При REPEATABLE READ - -- и выше этого недостаточно. - PERFORM pg_advisory_xact_lock(hashtext('v3.project.technical_number'), p_org_unit_id); - - -- Порядковый счётчик проекта для данного РФ/ВСП (org_unit) - SELECT COALESCE(MAX(right(technical_number, 2)::int), 0) + 1 - INTO v_seq - FROM v3.project - WHERE org_unit_id = p_org_unit_id - AND technical_number IS NOT NULL; - - IF v_seq > 99 THEN - RAISE EXCEPTION 'Исчерпан счётчик технических номеров проектов для org_unit id=% (максимум 99)', p_org_unit_id; - END IF; - - v_technical_number := to_char(now(), 'YYMM') || '_' - || lpad(p_org_unit_id::text, 4, '0') - || lpad(v_seq::text, 2, '0'); - - INSERT INTO v3.project ( - name, level, parent_id, org_unit_id, - project_type, vsp_format, placement_type, object_address, staff_count, total_area, - system_code, technical_number - ) VALUES ( - p_name, p_level, p_parent_id, p_org_unit_id, - p_project_type, p_vsp_format, p_placement_type, p_object_address, p_staff_count, p_total_area, - p_system_code, v_technical_number - ) RETURNING id INTO v_pid; - - -- Первый год: 2 отчёта (LIMIT + CURRENT_EXPENSES) + snapshot фаз + сетка статей. - SELECT y.limit_report_id, y.current_expenses_report_id - INTO v_lim, v_cur - FROM v3.add_project_year(v_pid, p_year, false) y; - - -- Аудит: PROJECT_CREATE — все заполненные поля + id отчётов - PERFORM v3.log_event( - 'PROJECT_CREATE', 'PROJECT', - jsonb_strip_nulls(jsonb_build_object( - 'project_id', v_pid, - 'name', p_name, - 'year', p_year, - 'level', p_level, - 'parent_id', p_parent_id, - 'org_unit_id', p_org_unit_id, - 'project_type', p_project_type, - 'vsp_format', p_vsp_format, - 'placement_type', p_placement_type, - 'object_address', p_object_address, - 'system_code', p_system_code, - 'technical_number', v_technical_number, - 'staff_count', p_staff_count, - 'total_area', p_total_area, - 'limit_report_id', v_lim, - 'current_expenses_report_id', v_cur - )) - ); - - RETURN QUERY SELECT v_pid, v_lim, v_cur; -END; -$function$; diff --git a/api/alembic/versions/sql/0051_form2_ahr_satellite_new_line.sql b/api/alembic/versions/sql/0051_form2_ahr_satellite_new_line.sql index 9ee6b09..0cf988f 100644 --- a/api/alembic/versions/sql/0051_form2_ahr_satellite_new_line.sql +++ b/api/alembic/versions/sql/0051_form2_ahr_satellite_new_line.sql @@ -226,3 +226,200 @@ $function$; -- нигде не вызывают (актуальный путь — ...detail_sync_line/...detail_sync_values). DROP FUNCTION IF EXISTS v3._upsert_form2_ahr_sync_values(INT, INT, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC, NUMERIC); DROP FUNCTION IF EXISTS v3._ensure_form2_ahr_sync_line(INT, INT); + + + +-- AURORA-1844: v3.upd_form_cells возвращает затронутые строки целиком. +-- Убран снимок «до» и _jsonb_diff: после применения правок выполняется один +-- вызов v_form_view (внутри v3._form_affected_rows), ответ — полные строки +-- изменённых INPUT и всех их предков-агрегатов (включая неизменившиеся). +-- Обёртка с p_user_id (0031) и upd_form_cell не меняются. + +CREATE OR REPLACE FUNCTION v3._form_affected_rows(p_form_id integer, p_sheet character varying, p_ids integer[], p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql +AS $function$ +DECLARE + v_form_type VARCHAR; + v_strip TEXT[] := ARRAY[]::TEXT[]; + v_lc_path INT[]; + v_eid_set INT[]; + v_ei_path INT[]; +BEGIN + SELECT bf.form_type_code INTO v_form_type + FROM v3.budget_form bf + WHERE bf.id = p_form_id; + + -- Ключи верхнего уровня исключённых разделов (при p_sections они приходят как null + -- и затёрли бы данные клиента). Вложенные null не трогаем: это очистка ячейки. + IF p_sections IS NOT NULL THEN + SELECT COALESCE(array_agg(k), ARRAY[]::TEXT[]) + INTO v_strip + FROM unnest(ARRAY['plan','seq_dfip','seq_ssp','approved','contract','booking', + 'contract_summary','allocation','collegial','ckk', + 'sequestration','reserve','contract_detail', + 'q1','q2','q3','q4','totals', + 'fact_q1','fact_q2','fact_q3','fact_q4']) AS k + WHERE NOT (k = ANY(p_sections)); + END IF; + + IF p_sheet IN ('AHR_RENT','AHR_UTILITY','AHR_SECURITY') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE v.row_type = 'INPUT' AND (v.data->>'id')::INT = ANY(p_ids) + ORDER BY v.sort_order; + + ELSIF p_sheet = 'AHR_LIMIT' THEN + v_lc_path := v3._limit_template_path_set(p_ids); + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE (v.data->>'id')::INT = ANY(v_lc_path) + ORDER BY v.sort_order; + + ELSIF p_sheet = 'OTCH9F' THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE EXISTS ( + SELECT 1 FROM v3.fixed_asset_report far + WHERE far.id = ANY(p_ids) + AND far.expense_item_id = (v.data->>'expense_item_id')::INT + AND far.equipment_name IS NOT DISTINCT FROM (v.data->>'equipment_name')) + ORDER BY v.sort_order; + + ELSE + SELECT array_agg(DISTINCT bl.expense_item_id) + INTO v_eid_set + FROM v3.budget_line bl + WHERE bl.id = ANY(p_ids); + v_ei_path := v3._expense_item_path_set(v_eid_set); + + IF v_form_type = 'FORM_4' THEN + -- ROOT раздела, GROUP по program_id и ITEM по project_id изменённых строк + -- (у GROUP/ITEM FORM_4 expense_item_id = id раздела, поэтому фильтр + -- по expense_item_id захватил бы все программы и проекты раздела). + RETURN QUERY + WITH vv AS MATERIALIZED ( + SELECT f.row_type, f.depth, f.sort_order, f.data + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) f + WHERE f.row_type <> 'META' + ), + chg AS ( + SELECT DISTINCT (x.data->'header'->>'program_id')::INT AS program_id, + (x.data->'header'->>'project_id')::INT AS project_id + FROM vv x + WHERE x.row_type = 'INPUT' AND (x.data->>'line_id')::INT = ANY(p_ids) + ) + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM vv v + WHERE (v.row_type = 'INPUT' AND (v.data->>'line_id')::INT = ANY(p_ids)) + OR (v.row_type = 'ROOT' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) + OR (v.row_type = 'GROUP' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) + AND (v.data->'header'->>'program_id')::INT IN (SELECT c.program_id FROM chg c)) + OR (v.row_type = 'ITEM' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) + AND (v.data->'header'->>'project_id')::INT IN (SELECT c.project_id FROM chg c)) + ORDER BY v.sort_order; + ELSE + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM') + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) + OR (v.row_type = 'INPUT' + AND (v.data->>'line_id')::INT = ANY(p_ids)) + ORDER BY v.sort_order; + END IF; + END IF; +END; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.upd_form_cells(p_form_id integer, p_sheet character varying, p_changes jsonb, p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql +AS $function$ +DECLARE + v_change JSONB; + v_line_id INT; + v_column TEXT; + v_changed_lines INT[] := ARRAY[]::INT[]; +BEGIN + IF p_changes IS NULL OR jsonb_typeof(p_changes) <> 'array' THEN + RAISE EXCEPTION 'p_changes must be a JSONB array'; + END IF; + + IF NOT EXISTS (SELECT 1 FROM v3.budget_form WHERE id = p_form_id) THEN + RAISE EXCEPTION 'budget_form id=% не существует', p_form_id; + END IF; + + FOR v_change IN SELECT * FROM jsonb_array_elements(p_changes) + LOOP + v_line_id := (v_change->>'line_id')::INT; + v_column := v_change->>'column'; + + IF v_line_id IS NULL OR v_column IS NULL THEN + RAISE EXCEPTION 'change must have line_id and column: %', v_change; + END IF; + + IF p_sheet = 'AHR_LIMIT' THEN + IF NOT EXISTS (SELECT 1 FROM v3.limit_template lt + WHERE lt.id = v_line_id AND lt.row_type = 'LEAF') THEN + RAISE EXCEPTION 'limit_template.id=% не существует или не LEAF', v_line_id; + END IF; + ELSIF p_sheet = 'OTCH9F' THEN + IF NOT EXISTS (SELECT 1 FROM v3.fixed_asset_report + WHERE id = v_line_id AND budget_form_id = p_form_id) THEN + RAISE EXCEPTION 'fixed_asset_report.id=% не принадлежит budget_form id=%', v_line_id, p_form_id; + END IF; + ELSIF p_sheet = 'AHR_RENT' THEN + IF NOT EXISTS (SELECT 1 FROM v3.rent_detail rd + JOIN v3.budget_line bl ON bl.id = rd.line_id + WHERE rd.id = v_line_id AND bl.budget_form_id = p_form_id) THEN + RAISE EXCEPTION 'rent_detail id=% не принадлежит budget_form id=%', v_line_id, p_form_id; + END IF; + ELSIF p_sheet = 'AHR_UTILITY' THEN + IF NOT EXISTS (SELECT 1 FROM v3.utility_detail ud + JOIN v3.budget_line bl ON bl.id = ud.line_id + WHERE ud.id = v_line_id AND bl.budget_form_id = p_form_id) THEN + RAISE EXCEPTION 'utility_detail id=% не принадлежит budget_form id=%', v_line_id, p_form_id; + END IF; + ELSIF p_sheet = 'AHR_SECURITY' THEN + IF NOT EXISTS (SELECT 1 FROM v3.security_detail sd + JOIN v3.budget_line bl ON bl.id = sd.line_id + WHERE sd.id = v_line_id AND bl.budget_form_id = p_form_id) THEN + RAISE EXCEPTION 'security_detail id=% не принадлежит budget_form id=%', v_line_id, p_form_id; + END IF; + ELSE + IF NOT EXISTS (SELECT 1 FROM v3.budget_line + WHERE id = v_line_id AND budget_form_id = p_form_id) THEN + RAISE EXCEPTION 'budget_line id=% не принадлежит budget_form id=%', v_line_id, p_form_id; + END IF; + END IF; + + IF NOT (v_line_id = ANY(v_changed_lines)) THEN + v_changed_lines := v_changed_lines || v_line_id; + END IF; + END LOOP; + + FOR v_change IN SELECT * FROM jsonb_array_elements(p_changes) + LOOP + PERFORM v3._apply_form_cell( + (v_change->>'line_id')::INT, + v_change->>'column', + v_change->'value', + p_sheet, + p_form_id); + END LOOP; + + RETURN QUERY + SELECT r.row_type, r.depth, r.sort_order, r.data + FROM v3._form_affected_rows(p_form_id, p_sheet, v_changed_lines, p_direction, p_sections) r + ORDER BY r.sort_order; +END; +$function$ +; diff --git a/api/alembic/versions/sql/0051_upd_form_cells_full_rows.sql b/api/alembic/versions/sql/0051_upd_form_cells_full_rows.sql deleted file mode 100644 index 388d821..0000000 --- a/api/alembic/versions/sql/0051_upd_form_cells_full_rows.sql +++ /dev/null @@ -1,194 +0,0 @@ --- AURORA-1844: v3.upd_form_cells возвращает затронутые строки целиком. --- Убран снимок «до» и _jsonb_diff: после применения правок выполняется один --- вызов v_form_view (внутри v3._form_affected_rows), ответ — полные строки --- изменённых INPUT и всех их предков-агрегатов (включая неизменившиеся). --- Обёртка с p_user_id (0031) и upd_form_cell не меняются. - -CREATE OR REPLACE FUNCTION v3._form_affected_rows(p_form_id integer, p_sheet character varying, p_ids integer[], p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE plpgsql -AS $function$ -DECLARE - v_form_type VARCHAR; - v_strip TEXT[] := ARRAY[]::TEXT[]; - v_lc_path INT[]; - v_eid_set INT[]; - v_ei_path INT[]; -BEGIN - SELECT bf.form_type_code INTO v_form_type - FROM v3.budget_form bf - WHERE bf.id = p_form_id; - - -- Ключи верхнего уровня исключённых разделов (при p_sections они приходят как null - -- и затёрли бы данные клиента). Вложенные null не трогаем: это очистка ячейки. - IF p_sections IS NOT NULL THEN - SELECT COALESCE(array_agg(k), ARRAY[]::TEXT[]) - INTO v_strip - FROM unnest(ARRAY['plan','seq_dfip','seq_ssp','approved','contract','booking', - 'contract_summary','allocation','collegial','ckk', - 'sequestration','reserve','contract_detail', - 'q1','q2','q3','q4','totals', - 'fact_q1','fact_q2','fact_q3','fact_q4']) AS k - WHERE NOT (k = ANY(p_sections)); - END IF; - - IF p_sheet IN ('AHR_RENT','AHR_UTILITY','AHR_SECURITY') THEN - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE v.row_type = 'INPUT' AND (v.data->>'id')::INT = ANY(p_ids) - ORDER BY v.sort_order; - - ELSIF p_sheet = 'AHR_LIMIT' THEN - v_lc_path := v3._limit_template_path_set(p_ids); - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE (v.data->>'id')::INT = ANY(v_lc_path) - ORDER BY v.sort_order; - - ELSIF p_sheet = 'OTCH9F' THEN - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE EXISTS ( - SELECT 1 FROM v3.fixed_asset_report far - WHERE far.id = ANY(p_ids) - AND far.expense_item_id = (v.data->>'expense_item_id')::INT - AND far.equipment_name IS NOT DISTINCT FROM (v.data->>'equipment_name')) - ORDER BY v.sort_order; - - ELSE - SELECT array_agg(DISTINCT bl.expense_item_id) - INTO v_eid_set - FROM v3.budget_line bl - WHERE bl.id = ANY(p_ids); - v_ei_path := v3._expense_item_path_set(v_eid_set); - - IF v_form_type = 'FORM_4' THEN - -- ROOT раздела, GROUP по program_id и ITEM по project_id изменённых строк - -- (у GROUP/ITEM FORM_4 expense_item_id = id раздела, поэтому фильтр - -- по expense_item_id захватил бы все программы и проекты раздела). - RETURN QUERY - WITH vv AS MATERIALIZED ( - SELECT f.row_type, f.depth, f.sort_order, f.data - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) f - WHERE f.row_type <> 'META' - ), - chg AS ( - SELECT DISTINCT (x.data->'header'->>'program_id')::INT AS program_id, - (x.data->'header'->>'project_id')::INT AS project_id - FROM vv x - WHERE x.row_type = 'INPUT' AND (x.data->>'line_id')::INT = ANY(p_ids) - ) - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM vv v - WHERE (v.row_type = 'INPUT' AND (v.data->>'line_id')::INT = ANY(p_ids)) - OR (v.row_type = 'ROOT' - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) - OR (v.row_type = 'GROUP' - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) - AND (v.data->'header'->>'program_id')::INT IN (SELECT c.program_id FROM chg c)) - OR (v.row_type = 'ITEM' - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) - AND (v.data->'header'->>'project_id')::INT IN (SELECT c.project_id FROM chg c)) - ORDER BY v.sort_order; - ELSE - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM') - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) - OR (v.row_type = 'INPUT' - AND (v.data->>'line_id')::INT = ANY(p_ids)) - ORDER BY v.sort_order; - END IF; - END IF; -END; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.upd_form_cells(p_form_id integer, p_sheet character varying, p_changes jsonb, p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE plpgsql -AS $function$ -DECLARE - v_change JSONB; - v_line_id INT; - v_column TEXT; - v_changed_lines INT[] := ARRAY[]::INT[]; -BEGIN - IF p_changes IS NULL OR jsonb_typeof(p_changes) <> 'array' THEN - RAISE EXCEPTION 'p_changes must be a JSONB array'; - END IF; - - IF NOT EXISTS (SELECT 1 FROM v3.budget_form WHERE id = p_form_id) THEN - RAISE EXCEPTION 'budget_form id=% не существует', p_form_id; - END IF; - - FOR v_change IN SELECT * FROM jsonb_array_elements(p_changes) - LOOP - v_line_id := (v_change->>'line_id')::INT; - v_column := v_change->>'column'; - - IF v_line_id IS NULL OR v_column IS NULL THEN - RAISE EXCEPTION 'change must have line_id and column: %', v_change; - END IF; - - IF p_sheet = 'AHR_LIMIT' THEN - IF NOT EXISTS (SELECT 1 FROM v3.limit_template lt - WHERE lt.id = v_line_id AND lt.row_type = 'LEAF') THEN - RAISE EXCEPTION 'limit_template.id=% не существует или не LEAF', v_line_id; - END IF; - ELSIF p_sheet = 'OTCH9F' THEN - IF NOT EXISTS (SELECT 1 FROM v3.fixed_asset_report - WHERE id = v_line_id AND budget_form_id = p_form_id) THEN - RAISE EXCEPTION 'fixed_asset_report.id=% не принадлежит budget_form id=%', v_line_id, p_form_id; - END IF; - ELSIF p_sheet = 'AHR_RENT' THEN - IF NOT EXISTS (SELECT 1 FROM v3.rent_detail rd - JOIN v3.budget_line bl ON bl.id = rd.line_id - WHERE rd.id = v_line_id AND bl.budget_form_id = p_form_id) THEN - RAISE EXCEPTION 'rent_detail id=% не принадлежит budget_form id=%', v_line_id, p_form_id; - END IF; - ELSIF p_sheet = 'AHR_UTILITY' THEN - IF NOT EXISTS (SELECT 1 FROM v3.utility_detail ud - JOIN v3.budget_line bl ON bl.id = ud.line_id - WHERE ud.id = v_line_id AND bl.budget_form_id = p_form_id) THEN - RAISE EXCEPTION 'utility_detail id=% не принадлежит budget_form id=%', v_line_id, p_form_id; - END IF; - ELSIF p_sheet = 'AHR_SECURITY' THEN - IF NOT EXISTS (SELECT 1 FROM v3.security_detail sd - JOIN v3.budget_line bl ON bl.id = sd.line_id - WHERE sd.id = v_line_id AND bl.budget_form_id = p_form_id) THEN - RAISE EXCEPTION 'security_detail id=% не принадлежит budget_form id=%', v_line_id, p_form_id; - END IF; - ELSE - IF NOT EXISTS (SELECT 1 FROM v3.budget_line - WHERE id = v_line_id AND budget_form_id = p_form_id) THEN - RAISE EXCEPTION 'budget_line id=% не принадлежит budget_form id=%', v_line_id, p_form_id; - END IF; - END IF; - - IF NOT (v_line_id = ANY(v_changed_lines)) THEN - v_changed_lines := v_changed_lines || v_line_id; - END IF; - END LOOP; - - FOR v_change IN SELECT * FROM jsonb_array_elements(p_changes) - LOOP - PERFORM v3._apply_form_cell( - (v_change->>'line_id')::INT, - v_change->>'column', - v_change->'value', - p_sheet, - p_form_id); - END LOOP; - - RETURN QUERY - SELECT r.row_type, r.depth, r.sort_order, r.data - FROM v3._form_affected_rows(p_form_id, p_sheet, v_changed_lines, p_direction, p_sections) r - ORDER BY r.sort_order; -END; -$function$ -; diff --git a/api/alembic/versions/sql/0052_form2_ahr_limit_period_vat_units.sql b/api/alembic/versions/sql/0052_form2_ahr_limit_period_vat_units.sql index c2423d4..c8a4ccd 100644 --- a/api/alembic/versions/sql/0052_form2_ahr_limit_period_vat_units.sql +++ b/api/alembic/versions/sql/0052_form2_ahr_limit_period_vat_units.sql @@ -870,7 +870,7 @@ $function$; -- 5. Старая 4-аргументная сигнатура больше не вызывается — удаляем. -DROP FUNCTION v3._form2_ahr_limit_amount(character varying, character varying, numeric, numeric); +DROP FUNCTION IF EXISTS v3._form2_ahr_limit_amount(character varying, character varying, numeric, numeric); -- 6. Строка «Итого» (id=0) должна попадать в path-set, чтобы upd_form_cells @@ -912,3 +912,2796 @@ BEGIN END LOOP; END; $do$; + + +-- AURORA-1850 (change: openspec/changes/aurora-1850-upd-form-cells-subtree): правка ячейки пересчитывает только затронутое поддерево. +-- AURORA-1850: фокусные сборщики FORM_1/FORM_2, скелет с _sort_rank, _form_affected_rows и дельта AHR на фокусном пути, jit=off. + +DROP FUNCTION IF EXISTS v3.v_form2_view(integer, character varying, text[]); +DROP FUNCTION IF EXISTS v3.v_form2_sheet_jsonb(integer, character varying, text[]); +DROP FUNCTION IF EXISTS v3.v_form2_sheet_sections(integer, character varying, text[]); +DROP FUNCTION IF EXISTS v3.v_form1_sheet_jsonb(integer, character varying, character varying, text[]); +DROP FUNCTION IF EXISTS v3.v_form1_sheet_sections(integer, character varying, character varying, text[]); + +CREATE OR REPLACE FUNCTION v3.v_form2_sheet_sections(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) + RETURNS TABLE(row_type character varying, depth integer, line_id integer, col_section_code character varying, col_item_id character varying, col_num_group_id character varying, col_name character varying, col_vsp_id integer, col_vsp_address character varying, col_plan_q1 numeric, col_plan_q2 numeric, col_plan_q3 numeric, col_plan_q4 numeric, col_plan_year numeric, col_plan_comment character varying, col_seq_dfip_q1 numeric, col_seq_dfip_q2 numeric, col_seq_dfip_q3 numeric, col_seq_dfip_q4 numeric, col_seq_dfip_year numeric, col_seq_dfip_just character varying, col_seq_ssp_q1 numeric, col_seq_ssp_q2 numeric, col_seq_ssp_q3 numeric, col_seq_ssp_q4 numeric, col_seq_ssp_year numeric, col_seq_ssp_just character varying, col_appr_q1 numeric, col_appr_q2 numeric, col_appr_q3 numeric, col_appr_q4 numeric, col_appr_year numeric, col_cd_counterparty character varying, col_cd_reference character varying, col_cd_date date, col_cd_subject character varying, col_cd_currency character varying, col_cd_ceiling numeric, col_cd_vat_rate character varying, col_cd_deadline character varying, col_cd_scheme character varying, col_cd_act character varying, col_cd_comment character varying, col_book_q1 numeric, col_book_q2 numeric, col_book_q3 numeric, col_book_q4 numeric, col_book_next_q1 numeric, col_book_next_q2 numeric, col_book_next_q3 numeric, col_book_next_q4 numeric, col_q1_adj_current numeric, col_q1_adj_ssp numeric, col_q1_adj_reserve numeric, col_q1_adj_comment character varying, col_q1_corrected_plan numeric, col_q1_pay_date date, col_q1_pay_amount numeric, col_q1_pay_comment character varying, col_q1_pay_act character varying, col_q1_booking numeric, col_q1_actual_m1 numeric, col_q1_actual_m2 numeric, col_q1_actual_m3 numeric, col_q1_actual_quarter numeric, col_q1_residual_after_booking numeric, col_q1_residual_after_actual numeric, col_q1_transfer_q2 numeric, col_q1_transfer_q2_delay_acts numeric, col_q1_transfer_q2_delay_procurement numeric, col_q1_transfer_q2_economy_rf numeric, col_q1_transfer_next_comment character varying, col_q1_transfer_q3 numeric, col_q1_transfer_q4 numeric, col_q1_transfer_far_comment character varying, col_q1_transfer_econ numeric, col_q1_total numeric, col_q2_target_change numeric, col_q2_base_correction numeric, col_q2_base_correction_comment character varying, col_q2_revision_inc numeric, col_q2_revision_seq numeric, col_q2_revision_comment character varying, col_q2_new_plan numeric, col_q2_adj_current numeric, col_q2_adj_ssp numeric, col_q2_adj_reserve numeric, col_q2_adj_comment character varying, col_q2_corrected_plan numeric, col_q2_pay_date date, col_q2_pay_amount numeric, col_q2_pay_comment character varying, col_q2_pay_act character varying, col_q2_booking numeric, col_q2_actual_m1 numeric, col_q2_actual_m2 numeric, col_q2_actual_m3 numeric, col_q2_actual_quarter numeric, col_q2_residual_after_booking numeric, col_q2_residual_after_actual numeric, col_q2_transfer_q3 numeric, col_q2_transfer_q3_delay_acts numeric, col_q2_transfer_q3_delay_procurement numeric, col_q2_transfer_q3_economy_rf numeric, col_q2_transfer_next_comment character varying, col_q2_transfer_q4 numeric, col_q2_transfer_far_comment character varying, col_q2_transfer_econ numeric, col_q2_total numeric, col_q3_target_change numeric, col_q3_base_correction numeric, col_q3_base_correction_comment character varying, col_q3_revision_inc numeric, col_q3_revision_seq numeric, col_q3_revision_comment character varying, col_q3_new_plan numeric, col_q3_adj_current numeric, col_q3_adj_ssp numeric, col_q3_adj_reserve numeric, col_q3_adj_comment character varying, col_q3_corrected_plan numeric, col_q3_pay_date date, col_q3_pay_amount numeric, col_q3_pay_comment character varying, col_q3_pay_act character varying, col_q3_booking numeric, col_q3_actual_m1 numeric, col_q3_actual_m2 numeric, col_q3_actual_m3 numeric, col_q3_actual_quarter numeric, col_q3_residual_after_booking numeric, col_q3_residual_after_actual numeric, col_q3_transfer_q4 numeric, col_q3_transfer_q4_delay_acts numeric, col_q3_transfer_q4_delay_procurement numeric, col_q3_transfer_q4_economy_rf numeric, col_q3_transfer_next_comment character varying, col_q3_transfer_econ numeric, col_q3_total numeric, col_q4_target_change numeric, col_q4_base_correction numeric, col_q4_base_correction_comment character varying, col_q4_revision_inc numeric, col_q4_revision_seq numeric, col_q4_revision_comment character varying, col_q4_new_plan numeric, col_q4_adj_current numeric, col_q4_adj_ssp numeric, col_q4_adj_reserve numeric, col_q4_adj_comment character varying, col_q4_corrected_plan numeric, col_q4_pay_date date, col_q4_pay_amount numeric, col_q4_pay_comment character varying, col_q4_pay_act character varying, col_q4_booking numeric, col_q4_actual_m1 numeric, col_q4_actual_m2 numeric, col_q4_actual_m3 numeric, col_q4_actual_spod numeric, col_q4_actual_quarter numeric, col_q4_residual_after_booking numeric, col_q4_residual_after_actual numeric, col_q4_transfer_econ numeric, col_q4_total numeric, col_fact_year numeric, col_pay_year numeric, col_economy_year numeric, col_internal_order character varying, col_cs_total numeric, col_cs_counterparty character varying, col_cs_deadline character varying, col_cs_comment character varying, col_cs_future_y1 numeric, col_cs_future_y2 numeric, col_cs_other_ssp numeric, col_al_contract_ref character varying, col_al_purpose character varying, col_al_order character varying, col_al_property character varying, col_ca_approved numeric, col_ca_protocol character varying, col_ca_note character varying, col_ckk_ceiling numeric, col_ckk_rf_sched character varying, col_ckk_deadline character varying, col_ckk_proc_plan character varying, col_ckk_proc_meth character varying, col_ckk_comment character varying, col_cd_addenda character varying, col_cd_exp_q1 numeric, col_cd_exp_q2 numeric, col_cd_exp_q3 numeric, col_cd_exp_q4 numeric, col_cd_rf_sched character varying, col_cd_exchange_rate numeric, col_cd_amount_foreign numeric, col_q1_adj_rf numeric, col_q1_pay_ho numeric, col_q1_pay_rf numeric, col_q2_adj_rf numeric, col_q2_pay_ho numeric, col_q2_pay_rf numeric, col_q3_adj_rf numeric, col_q3_pay_ho numeric, col_q3_pay_rf numeric, col_q4_adj_rf numeric, col_q4_pay_ho numeric, col_q4_pay_rf numeric, _sort_path integer[], _sort_rank bigint) + LANGUAGE plpgsql + STABLE + SET jit TO 'off' +AS $function$ +#variable_conflict use_column +DECLARE + s_plan BOOL; s_seq_d BOOL; s_seq_s BOOL; s_appr BOOL; + s_cd BOOL; s_book BOOL; + s_cs BOOL; s_al BOOL; s_ca BOOL; s_ckk BOOL; -- НОВЫЕ блоки + s_q1 BOOL; s_q2 BOOL; s_q3 BOOL; s_q4 BOOL; s_tot BOOL; + s_need_ap BOOL; -- plan/seq/reserve нужны для approved + cp1..cp4 + v_focus_nodes INT[]; -- AURORA-1850: узлы фокуса (путь статей строк фокуса ∩ tw); NULL = весь лист + v_focus_eids INT[]; -- AURORA-1850: объединение desc_ids узлов фокуса +BEGIN + s_plan := p_sections IS NULL OR 'plan' = ANY(p_sections); + s_seq_d := p_sections IS NULL OR 'seq_dfip' = ANY(p_sections); + s_seq_s := p_sections IS NULL OR 'seq_ssp' = ANY(p_sections); + s_appr := p_sections IS NULL OR 'approved' = ANY(p_sections); + s_cd := p_sections IS NULL OR 'contract' = ANY(p_sections); + s_book := p_sections IS NULL OR 'booking' = ANY(p_sections); + s_cs := p_sections IS NULL OR 'contract_summary' = ANY(p_sections); + s_al := p_sections IS NULL OR 'allocation' = ANY(p_sections); + s_ca := p_sections IS NULL OR 'collegial' = ANY(p_sections); + s_ckk := p_sections IS NULL OR 'ckk' = ANY(p_sections); + s_q1 := p_sections IS NULL OR 'q1' = ANY(p_sections); + s_q2 := p_sections IS NULL OR 'q2' = ANY(p_sections); + s_q3 := p_sections IS NULL OR 'q3' = ANY(p_sections); + s_q4 := p_sections IS NULL OR 'q4' = ANY(p_sections); + s_tot := p_sections IS NULL OR 'totals' = ANY(p_sections); + s_need_ap := s_plan OR s_appr OR s_q1 OR s_q2 OR s_q3 OR s_q4; + + -- Фокус (D1): NULL = весь лист, '{}' = пустой результат. COALESCE обязателен: + -- пустой фокус не должен превратиться в NULL и провалиться в полную сборку. + IF p_focus_lines IS NOT NULL THEN + WITH fp AS ( + SELECT v3._expense_item_path_set( + (SELECT array_agg(DISTINCT bl.expense_item_id) + FROM v3.budget_line bl + WHERE bl.id = ANY(p_focus_lines))) AS ids + ), + fn AS ( + SELECT t.id, t.desc_ids + FROM v3.mv_expense_item_tree t + JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id + JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code + WHERE t.sheet = p_sheet + AND t.id = ANY(COALESCE((SELECT fp.ids FROM fp), '{}'::int[])) + ) + SELECT COALESCE((SELECT array_agg(fn.id) FROM fn), '{}'::int[]), + COALESCE((SELECT array_agg(DISTINCT d) FROM fn, unnest(fn.desc_ids) AS d), '{}'::int[]) + INTO v_focus_nodes, v_focus_eids; + END IF; + + RETURN QUERY + WITH + tw AS ( + SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, + t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids, + p.parent_item_id AS grandparent_item_id + FROM v3.mv_expense_item_tree t + LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id + JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id + JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code + WHERE t.sheet = p_sheet + ), + page AS ( + SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id, + bl.internal_order AS io + FROM v3.budget_line bl + JOIN v3.expense_item ei ON ei.id = bl.expense_item_id + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet + ), + tw_f AS ( + SELECT * FROM tw WHERE p_focus_lines IS NULL OR tw.id = ANY(v_focus_nodes) + ), + page_f AS ( + SELECT * FROM page WHERE p_focus_lines IS NULL OR page.lid = ANY(p_focus_lines) + ), + -- Скелет листа (D2): ключи всех узлов tw и всех строк page JOIN tw, без jsonb и сумм. + -- Ранг одинаков в обоих режимах; tie-break D6: узел раньше строки. + sk AS ( + SELECT n.k, + ROW_NUMBER() OVER (ORDER BY n._sort, n.lid NULLS FIRST) AS rnk + FROM ( + SELECT -t0.id::BIGINT AS k, NULL::INT AS lid, t0.path AS _sort FROM tw t0 + UNION ALL + SELECT pg0.lid::BIGINT, pg0.lid::INT, t1.path || ARRAY[pg0.lid::INT] + FROM page pg0 JOIN tw t1 ON t1.id = pg0.eid + ) n + ), + jp AS (SELECT p.* FROM v3.plan p JOIN page_f pg ON p.line_id = pg.lid WHERE s_need_ap), + jsd AS (SELECT s.* FROM v3.sequestration s JOIN page_f pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'), + jsg AS (SELECT s.* FROM v3.sequestration s JOIN page_f pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='SSP_GO'), + jr AS (SELECT r.* FROM v3.reserve r JOIN page_f pg ON r.line_id = pg.lid WHERE s_need_ap), + jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page_f pg ON c.line_id = pg.lid WHERE s_cd), + jck AS (SELECT c.* FROM v3.ckk c JOIN page_f pg ON c.line_id = pg.lid WHERE s_book OR s_ckk), + jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page_f pg ON c.line_id = pg.lid WHERE s_cs), + jal AS (SELECT a.* FROM v3.allocation a JOIN page_f pg ON a.line_id = pg.lid WHERE s_al), + jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page_f pg ON c.line_id = pg.lid WHERE s_ca), + jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1), + jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2), + jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3), + jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4), + + input_base AS ( + SELECT + pg.lid, pg.eid, pg.bname, pg.vsp_id, + v.address AS vsp_addr, + CASE + WHEN t.depth < 3 THEN t.item_id + WHEN t.depth = 3 THEN t.parent_item_id + WHEN t.depth = 4 THEN t.grandparent_item_id + END AS sc, + t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path, + COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2, + COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4, + p.comment AS pcmt, + COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2, + COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4, + sd.justification AS djust, + COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2, + COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4, + sg.justification AS gjust, + COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2, + COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4, + cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt, + cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil, + cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch, + cd.act AS cd_act, cd.comment AS cd_cmt, + ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4, + ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2, + ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4, + pg.io AS io, + cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl, + cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2, + cs.other_ssp_amount AS cs_oth, + al.contract_ref AS al_cref, al.allocation_purpose AS al_purp, + al.internal_order AS al_io, al.property_object AS al_prop, + ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note, + ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl, + ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt, + cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2, + cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf, + cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx, + q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, + q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf, + q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf, + q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf, + q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt, + q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa, + q1.payment_comment AS q1_pcmt, + q1.payment_act AS q1_pact, + COALESCE( + q1.booking_amount, + CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q1 + WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1 + ELSE cd.expenses_q1 + END + + ) AS q1_book, + q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3, + q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4, + q1.transfer_to_economy AS q1_te, + q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp, + q1.transfer_economy_rf AS q1_terf, + q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc, + q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc, + q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq, + q2.plan_revision_comment AS q2_rcmt, + q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv, + q2.adj_comment AS q2_acmt, + q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa, + q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact, + COALESCE( + q2.booking_amount, + CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q2 + WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2 + ELSE cd.expenses_q2 + END + + ) AS q2_book, + q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3, + q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te, + q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp, + q2.transfer_economy_rf AS q2_terf, + q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc, + q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc, + q3.base_plan_correction_comment AS q3_bcc, + q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq, + q3.plan_revision_comment AS q3_rcmt, + q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv, + q3.adj_comment AS q3_acmt, + q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa, + q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact, + COALESCE( + q3.booking_amount, + CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q3 + WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3 + ELSE cd.expenses_q3 + END + + ) AS q3_book, + q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3, + q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te, + q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp, + q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc, + q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc, + q4.base_plan_correction_comment AS q4_bcc, + q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq, + q4.plan_revision_comment AS q4_rcmt, + q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv, + q4.adj_comment AS q4_acmt, + q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa, + q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact, + COALESCE( + q4.booking_amount, + CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q4 + WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4 + ELSE cd.expenses_q4 + END + + ) AS q4_book, + q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod, + q4.transfer_to_economy AS q4_te, + COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1, + COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2, + COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3, + COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4 + FROM page_f pg + JOIN tw t ON t.id = pg.eid + LEFT JOIN v3.vsp v ON v.id = pg.vsp_id + LEFT JOIN jp p ON p.line_id = pg.lid + LEFT JOIN jsd sd ON sd.line_id = pg.lid + LEFT JOIN jsg sg ON sg.line_id = pg.lid + LEFT JOIN jr r ON r.line_id = pg.lid + LEFT JOIN jcd cd ON cd.line_id = pg.lid + LEFT JOIN jck ck ON ck.line_id = pg.lid + LEFT JOIN jcs cs ON cs.line_id = pg.lid + LEFT JOIN jal al ON al.line_id = pg.lid + LEFT JOIN jca ca ON ca.line_id = pg.lid + LEFT JOIN jq1 q1 ON q1.line_id = pg.lid + LEFT JOIN jq2 q2 ON q2.line_id = pg.lid + LEFT JOIN jq3 q3 ON q3.line_id = pg.lid + LEFT JOIN jq4 q4 ON q4.line_id = pg.lid + ), + enriched AS ( + SELECT b.*, + b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1, + COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1, + b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2, + COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2, + b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3, + COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3, + b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4, + COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4 + FROM input_base b + ), + final_input AS ( + SELECT e.*, + e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2, + e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3, + e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4 + FROM enriched e + ), + + agg AS ( + SELECT bl.expense_item_id AS eid, + SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4, + SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4, + SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4, + SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4, + SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4, + SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4, + SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2, + SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4 + FROM v3.budget_line bl + JOIN v3.expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap + LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap + LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND s_need_ap + LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap + LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book + LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet + AND (s_need_ap OR s_book OR s_cd) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id + ), + aq_q AS ( + SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter, + SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv, + SUM(q.payment_amount) AS pa, + SUM( + COALESCE( + q.booking_amount, + CASE + WHEN qrtrs.qrtr = 1 + THEN CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q1 + WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1 + ELSE cd.expenses_q1 + END + WHEN qrtrs.qrtr = 2 THEN CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q2 + WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2 + ELSE cd.expenses_q2 + END + WHEN qrtrs.qrtr = 3 THEN CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q3 + WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3 + ELSE cd.expenses_q3 + END + WHEN qrtrs.qrtr = 4 THEN CASE + WHEN p_sheet = 'AHR' THEN ck.expenses_q4 + WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4 + ELSE cd.expenses_q4 + END + END + + )) AS bk, + SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3, + SUM(q.actual_spod) AS spod, + SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4, + SUM(q.transfer_to_economy) AS te, + SUM(q.transfer_delay_acts) AS tda, + SUM(q.transfer_delay_procurement) AS tdp, + SUM(q.transfer_economy_rf) AS terf, + SUM(COALESCE(q.plan_revision_increase,0) + + COALESCE(q.plan_revision_sequester,0) + + COALESCE(q.target_change,0) + + COALESCE(q.base_plan_correction,0)) AS rev + FROM v3.budget_line bl + CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr) + + JOIN v3.expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr + LEFT JOIN v3.ckk ck ON bl.id = ck.line_id + LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id, qrtrs.qrtr + ), + tw_agg AS ( + SELECT tw.id, + SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4, + SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4, + SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4, + SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4, + SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4, + SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4, + SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4 + FROM tw_f tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids) + GROUP BY tw.id + ), + tw_aq1 AS ( + SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.bk) AS bk, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, + SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf + FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id + ), + tw_aq2 AS ( + SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.bk) AS bk, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev, + SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf + FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id + ), + tw_aq3 AS ( + SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.bk) AS bk, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev, + SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf + FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id + ), + tw_aq4 AS ( + SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.bk) AS bk, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod, + SUM(b.te) AS te, SUM(b.rev) AS rev + FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id + ) + + SELECT sub.row_type, sub.depth, sub.line_id, sub.col_section_code, sub.col_item_id, sub.col_num_group_id, sub.col_name, sub.col_vsp_id, sub.col_vsp_address, sub.col_plan_q1, sub.col_plan_q2, sub.col_plan_q3, sub.col_plan_q4, sub.col_plan_year, sub.col_plan_comment, sub.col_seq_dfip_q1, sub.col_seq_dfip_q2, sub.col_seq_dfip_q3, sub.col_seq_dfip_q4, sub.col_seq_dfip_year, sub.col_seq_dfip_just, sub.col_seq_ssp_q1, sub.col_seq_ssp_q2, sub.col_seq_ssp_q3, sub.col_seq_ssp_q4, sub.col_seq_ssp_year, sub.col_seq_ssp_just, sub.col_appr_q1, sub.col_appr_q2, sub.col_appr_q3, sub.col_appr_q4, sub.col_appr_year, sub.col_cd_counterparty, sub.col_cd_reference, sub.col_cd_date, sub.col_cd_subject, sub.col_cd_currency, sub.col_cd_ceiling, sub.col_cd_vat_rate, sub.col_cd_deadline, sub.col_cd_scheme, sub.col_cd_act, sub.col_cd_comment, sub.col_book_q1, sub.col_book_q2, sub.col_book_q3, sub.col_book_q4, sub.col_book_next_q1, sub.col_book_next_q2, sub.col_book_next_q3, sub.col_book_next_q4, sub.col_q1_adj_current, sub.col_q1_adj_ssp, sub.col_q1_adj_reserve, sub.col_q1_adj_comment, sub.col_q1_corrected_plan, sub.col_q1_pay_date, sub.col_q1_pay_amount, sub.col_q1_pay_comment, sub.col_q1_pay_act, sub.col_q1_booking, sub.col_q1_actual_m1, sub.col_q1_actual_m2, sub.col_q1_actual_m3, sub.col_q1_actual_quarter, sub.col_q1_residual_after_booking, sub.col_q1_residual_after_actual, sub.col_q1_transfer_q2, sub.col_q1_transfer_q2_delay_acts, sub.col_q1_transfer_q2_delay_procurement, sub.col_q1_transfer_q2_economy_rf, sub.col_q1_transfer_next_comment, sub.col_q1_transfer_q3, sub.col_q1_transfer_q4, sub.col_q1_transfer_far_comment, sub.col_q1_transfer_econ, sub.col_q1_total, sub.col_q2_target_change, sub.col_q2_base_correction, sub.col_q2_base_correction_comment, sub.col_q2_revision_inc, sub.col_q2_revision_seq, sub.col_q2_revision_comment, sub.col_q2_new_plan, sub.col_q2_adj_current, sub.col_q2_adj_ssp, sub.col_q2_adj_reserve, sub.col_q2_adj_comment, sub.col_q2_corrected_plan, sub.col_q2_pay_date, sub.col_q2_pay_amount, sub.col_q2_pay_comment, sub.col_q2_pay_act, sub.col_q2_booking, sub.col_q2_actual_m1, sub.col_q2_actual_m2, sub.col_q2_actual_m3, sub.col_q2_actual_quarter, sub.col_q2_residual_after_booking, sub.col_q2_residual_after_actual, sub.col_q2_transfer_q3, sub.col_q2_transfer_q3_delay_acts, sub.col_q2_transfer_q3_delay_procurement, sub.col_q2_transfer_q3_economy_rf, sub.col_q2_transfer_next_comment, sub.col_q2_transfer_q4, sub.col_q2_transfer_far_comment, sub.col_q2_transfer_econ, sub.col_q2_total, sub.col_q3_target_change, sub.col_q3_base_correction, sub.col_q3_base_correction_comment, sub.col_q3_revision_inc, sub.col_q3_revision_seq, sub.col_q3_revision_comment, sub.col_q3_new_plan, sub.col_q3_adj_current, sub.col_q3_adj_ssp, sub.col_q3_adj_reserve, sub.col_q3_adj_comment, sub.col_q3_corrected_plan, sub.col_q3_pay_date, sub.col_q3_pay_amount, sub.col_q3_pay_comment, sub.col_q3_pay_act, sub.col_q3_booking, sub.col_q3_actual_m1, sub.col_q3_actual_m2, sub.col_q3_actual_m3, sub.col_q3_actual_quarter, sub.col_q3_residual_after_booking, sub.col_q3_residual_after_actual, sub.col_q3_transfer_q4, sub.col_q3_transfer_q4_delay_acts, sub.col_q3_transfer_q4_delay_procurement, sub.col_q3_transfer_q4_economy_rf, sub.col_q3_transfer_next_comment, sub.col_q3_transfer_econ, sub.col_q3_total, sub.col_q4_target_change, sub.col_q4_base_correction, sub.col_q4_base_correction_comment, sub.col_q4_revision_inc, sub.col_q4_revision_seq, sub.col_q4_revision_comment, sub.col_q4_new_plan, sub.col_q4_adj_current, sub.col_q4_adj_ssp, sub.col_q4_adj_reserve, sub.col_q4_adj_comment, sub.col_q4_corrected_plan, sub.col_q4_pay_date, sub.col_q4_pay_amount, sub.col_q4_pay_comment, sub.col_q4_pay_act, sub.col_q4_booking, sub.col_q4_actual_m1, sub.col_q4_actual_m2, sub.col_q4_actual_m3, sub.col_q4_actual_spod, sub.col_q4_actual_quarter, sub.col_q4_residual_after_booking, sub.col_q4_residual_after_actual, sub.col_q4_transfer_econ, sub.col_q4_total, sub.col_fact_year, sub.col_pay_year, sub.col_economy_year, sub.col_internal_order, sub.col_cs_total, sub.col_cs_counterparty, sub.col_cs_deadline, sub.col_cs_comment, sub.col_cs_future_y1, sub.col_cs_future_y2, sub.col_cs_other_ssp, sub.col_al_contract_ref, sub.col_al_purpose, sub.col_al_order, sub.col_al_property, sub.col_ca_approved, sub.col_ca_protocol, sub.col_ca_note, sub.col_ckk_ceiling, sub.col_ckk_rf_sched, sub.col_ckk_deadline, sub.col_ckk_proc_plan, sub.col_ckk_proc_meth, sub.col_ckk_comment, sub.col_cd_addenda, sub.col_cd_exp_q1, sub.col_cd_exp_q2, sub.col_cd_exp_q3, sub.col_cd_exp_q4, sub.col_cd_rf_sched, sub.col_cd_exchange_rate, sub.col_cd_amount_foreign, sub.col_q1_adj_rf, sub.col_q1_pay_ho, sub.col_q1_pay_rf, sub.col_q2_adj_rf, sub.col_q2_pay_ho, sub.col_q2_pay_rf, sub.col_q3_adj_rf, sub.col_q3_pay_ho, sub.col_q3_pay_rf, sub.col_q4_adj_rf, sub.col_q4_pay_ho, sub.col_q4_pay_rf, sub._sort_path, sk.rnk + FROM ( + SELECT + 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT, + f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr, + CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END, + CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END, + CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END, + CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END, + CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END, + CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END, + CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END, + CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END, + CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END, + CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END, + CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END, + CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END, + CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END, + CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END, + CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END, + CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END, + CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END, + CASE WHEN s_cd THEN f.cd_cmt END, + CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END, + CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END, + CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END, + CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END, + CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END, + CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END, + CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END, + CASE WHEN s_q1 THEN f.q1_pcmt END, + CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END, + CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END, + CASE WHEN s_q1 THEN f.aq1 END, + CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking + CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual + CASE WHEN s_q1 THEN f.q1_tq2 END, + CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END, + CASE WHEN s_q1 THEN f.q1_tnc END, + CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END, + CASE WHEN s_q1 THEN f.q1_tfc END, + CASE WHEN s_q1 THEN f.q1_te END, + CASE WHEN s_q1 THEN + COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0) + +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) + END, + CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END, + CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END, + CASE WHEN s_q2 THEN f.q2_rcmt END, + CASE WHEN s_q2 THEN f.np2 END, + CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END, + CASE WHEN s_q2 THEN f.q2_acmt END, + CASE WHEN s_q2 THEN f.cp2 END, + CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END, + CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END, + CASE WHEN s_q2 THEN f.q2_book END, + CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END, + CASE WHEN s_q2 THEN f.aq2 END, + CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END, + CASE WHEN s_q2 THEN f.cp2 - f.aq2 END, + CASE WHEN s_q2 THEN f.q2_tq3 END, + CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END, + CASE WHEN s_q2 THEN f.q2_tnc END, + CASE WHEN s_q2 THEN f.q2_tq4 END, + CASE WHEN s_q2 THEN f.q2_tfc END, + CASE WHEN s_q2 THEN f.q2_te END, + CASE WHEN s_q2 THEN + COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0) + +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) + END, + CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END, + CASE WHEN s_q3 THEN f.q3_bcc END, + CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END, + CASE WHEN s_q3 THEN f.q3_rcmt END, + CASE WHEN s_q3 THEN f.np3 END, + CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END, + CASE WHEN s_q3 THEN f.q3_acmt END, + CASE WHEN s_q3 THEN f.cp3 END, + CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END, + CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END, + CASE WHEN s_q3 THEN f.q3_book END, + CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END, + CASE WHEN s_q3 THEN f.aq3 END, + CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END, + CASE WHEN s_q3 THEN f.cp3 - f.aq3 END, + CASE WHEN s_q3 THEN f.q3_tq4 END, + CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END, + CASE WHEN s_q3 THEN f.q3_tnc END, + CASE WHEN s_q3 THEN f.q3_te END, + CASE WHEN s_q3 THEN + COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0) + +COALESCE(f.q3_te,0) + END, + CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END, + CASE WHEN s_q4 THEN f.q4_bcc END, + CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END, + CASE WHEN s_q4 THEN f.q4_rcmt END, + CASE WHEN s_q4 THEN f.np4 END, + CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END, + CASE WHEN s_q4 THEN f.q4_acmt END, + CASE WHEN s_q4 THEN f.cp4 END, + CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END, + CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END, + CASE WHEN s_q4 THEN f.q4_book END, + CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END, + CASE WHEN s_q4 THEN f.q4_spod END, + CASE WHEN s_q4 THEN f.aq4 END, + CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END, + CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, + CASE WHEN s_q4 THEN f.q4_te END, + CASE WHEN s_q4 THEN f.q4_te END, + CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, + CASE WHEN s_tot THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END, + CASE WHEN s_tot THEN f.cp4 - f.aq4 END, + + f.io, + CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END, + CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END, + CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END, + CASE WHEN s_cs THEN f.cs_oth END, + CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END, + CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END, + CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END, + CASE WHEN s_ca THEN f.ca_note END, + CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END, + CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END, + CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END, + CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END, + CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END, + CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END, + CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END, + CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, + CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END, + CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END, + CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END, + + f.tree_path || ARRAY[f.lid::INT] AS _sort, + f.lid::BIGINT AS _k + FROM final_input f + + UNION ALL + + SELECT + CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR, + t.depth, NULL::INT, + CASE + WHEN t.depth < 3 THEN t.item_id + WHEN t.depth = 3 THEN t.parent_item_id + WHEN t.depth = 4 THEN t.grandparent_item_id + END, + CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END, + t.num_group_id, t.name, NULL::INT, NULL::VARCHAR, + CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END, + CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END, + CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END, + NULL::VARCHAR, + CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END, + CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END, + CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END, + NULL::VARCHAR, + CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END, + CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END, + CASE WHEN s_seq_s THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END, + NULL::VARCHAR, + CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END, + CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END, + CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END, + CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END, + CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) + +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) + +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) + +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END, + NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR, + NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, + NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END, + CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END, + CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END, + CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END, + CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END, + NULL::VARCHAR, + CASE WHEN s_q1 THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END, + NULL::DATE, + CASE WHEN s_q1 THEN tb1.pa END, + NULL::VARCHAR, -- pay_comment + NULL::VARCHAR, -- pay_act + CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup) + CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END, + CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0)) + - COALESCE(tb1.bk,0) + END, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0)) + - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)) + END, + CASE WHEN s_q1 THEN tb1.tq2 END, + CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END, + NULL::VARCHAR, -- transfer_next_comment (text, no rollup) + CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END, + NULL::VARCHAR, -- far comment + CASE WHEN s_q1 THEN tb1.te END, + CASE WHEN s_q1 THEN + COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0) + +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0) + END, + NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction + NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq + NULL::VARCHAR, -- revision_comment + CASE WHEN s_q2 THEN + COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0) + END, + CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END, + NULL::VARCHAR, -- adj_comment + CASE WHEN s_q2 THEN + COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0) + END, + NULL::DATE, + CASE WHEN s_q2 THEN tb2.pa END, + NULL::VARCHAR, -- pay_comment + NULL::VARCHAR, -- pay_act + CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup) + CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END, + CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)) + - COALESCE(tb2.bk,0) + END, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)) + - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)) + END, + CASE WHEN s_q2 THEN tb2.tq3 END, + CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END, + NULL::VARCHAR, -- transfer_next_comment (text, no rollup) + CASE WHEN s_q2 THEN tb2.tq4 END, + NULL::VARCHAR, -- far comment + CASE WHEN s_q2 THEN tb2.te END, + CASE WHEN s_q2 THEN + COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0) + +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0) + END, + NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment + NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq + NULL::VARCHAR, + CASE WHEN s_q3 THEN + COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0) + END, + CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END, + NULL::VARCHAR, + CASE WHEN s_q3 THEN + COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0) + END, + NULL::DATE, + CASE WHEN s_q3 THEN tb3.pa END, + NULL::VARCHAR, -- pay_comment + NULL::VARCHAR, -- pay_act + CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup) + CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END, + CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)) + - COALESCE(tb3.bk,0) + END, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)) + - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)) + END, + CASE WHEN s_q3 THEN tb3.tq4 END, + CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END, + NULL::VARCHAR, -- transfer_next_comment (text, no rollup) + CASE WHEN s_q3 THEN tb3.te END, + CASE WHEN s_q3 THEN + COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0) + +COALESCE(tb3.te,0) + END, + NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment + NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq + NULL::VARCHAR, + CASE WHEN s_q4 THEN + COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0) + END, + CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END, + NULL::VARCHAR, + CASE WHEN s_q4 THEN + COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0) + END, + NULL::DATE, + CASE WHEN s_q4 THEN tb4.pa END, + NULL::VARCHAR, -- pay_comment + NULL::VARCHAR, -- pay_act + CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup) + CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END, + CASE WHEN s_q4 THEN tb4.spod END, + CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)) + - COALESCE(tb4.bk,0) + END, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)) + - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)) + END, + CASE WHEN s_q4 THEN tb4.te END, + CASE WHEN s_q4 THEN tb4.te END, + CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) + +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) + +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) + +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, + CASE WHEN s_tot THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END, + CASE WHEN s_tot THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) + +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0) + +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)) + - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)) + END, + + NULL::VARCHAR, -- internal_order + NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary + NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, + NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation + NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial + NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk + NULL::VARCHAR, NULL::VARCHAR, + NULL::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END, + CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END, + NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC, + NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf + NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2 + NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3 + NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4 + + t.path AS _sort, + -t.id::BIGINT + FROM tw_f t + LEFT JOIN tw_agg ta ON ta.id = t.id + LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id + LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id + LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id + LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id + ) sub(row_type, depth, line_id, col_section_code, col_item_id, col_num_group_id, col_name, col_vsp_id, col_vsp_address, col_plan_q1, col_plan_q2, col_plan_q3, col_plan_q4, col_plan_year, col_plan_comment, col_seq_dfip_q1, col_seq_dfip_q2, col_seq_dfip_q3, col_seq_dfip_q4, col_seq_dfip_year, col_seq_dfip_just, col_seq_ssp_q1, col_seq_ssp_q2, col_seq_ssp_q3, col_seq_ssp_q4, col_seq_ssp_year, col_seq_ssp_just, col_appr_q1, col_appr_q2, col_appr_q3, col_appr_q4, col_appr_year, col_cd_counterparty, col_cd_reference, col_cd_date, col_cd_subject, col_cd_currency, col_cd_ceiling, col_cd_vat_rate, col_cd_deadline, col_cd_scheme, col_cd_act, col_cd_comment, col_book_q1, col_book_q2, col_book_q3, col_book_q4, col_book_next_q1, col_book_next_q2, col_book_next_q3, col_book_next_q4, col_q1_adj_current, col_q1_adj_ssp, col_q1_adj_reserve, col_q1_adj_comment, col_q1_corrected_plan, col_q1_pay_date, col_q1_pay_amount, col_q1_pay_comment, col_q1_pay_act, col_q1_booking, col_q1_actual_m1, col_q1_actual_m2, col_q1_actual_m3, col_q1_actual_quarter, col_q1_residual_after_booking, col_q1_residual_after_actual, col_q1_transfer_q2, col_q1_transfer_q2_delay_acts, col_q1_transfer_q2_delay_procurement, col_q1_transfer_q2_economy_rf, col_q1_transfer_next_comment, col_q1_transfer_q3, col_q1_transfer_q4, col_q1_transfer_far_comment, col_q1_transfer_econ, col_q1_total, col_q2_target_change, col_q2_base_correction, col_q2_base_correction_comment, col_q2_revision_inc, col_q2_revision_seq, col_q2_revision_comment, col_q2_new_plan, col_q2_adj_current, col_q2_adj_ssp, col_q2_adj_reserve, col_q2_adj_comment, col_q2_corrected_plan, col_q2_pay_date, col_q2_pay_amount, col_q2_pay_comment, col_q2_pay_act, col_q2_booking, col_q2_actual_m1, col_q2_actual_m2, col_q2_actual_m3, col_q2_actual_quarter, col_q2_residual_after_booking, col_q2_residual_after_actual, col_q2_transfer_q3, col_q2_transfer_q3_delay_acts, col_q2_transfer_q3_delay_procurement, col_q2_transfer_q3_economy_rf, col_q2_transfer_next_comment, col_q2_transfer_q4, col_q2_transfer_far_comment, col_q2_transfer_econ, col_q2_total, col_q3_target_change, col_q3_base_correction, col_q3_base_correction_comment, col_q3_revision_inc, col_q3_revision_seq, col_q3_revision_comment, col_q3_new_plan, col_q3_adj_current, col_q3_adj_ssp, col_q3_adj_reserve, col_q3_adj_comment, col_q3_corrected_plan, col_q3_pay_date, col_q3_pay_amount, col_q3_pay_comment, col_q3_pay_act, col_q3_booking, col_q3_actual_m1, col_q3_actual_m2, col_q3_actual_m3, col_q3_actual_quarter, col_q3_residual_after_booking, col_q3_residual_after_actual, col_q3_transfer_q4, col_q3_transfer_q4_delay_acts, col_q3_transfer_q4_delay_procurement, col_q3_transfer_q4_economy_rf, col_q3_transfer_next_comment, col_q3_transfer_econ, col_q3_total, col_q4_target_change, col_q4_base_correction, col_q4_base_correction_comment, col_q4_revision_inc, col_q4_revision_seq, col_q4_revision_comment, col_q4_new_plan, col_q4_adj_current, col_q4_adj_ssp, col_q4_adj_reserve, col_q4_adj_comment, col_q4_corrected_plan, col_q4_pay_date, col_q4_pay_amount, col_q4_pay_comment, col_q4_pay_act, col_q4_booking, col_q4_actual_m1, col_q4_actual_m2, col_q4_actual_m3, col_q4_actual_spod, col_q4_actual_quarter, col_q4_residual_after_booking, col_q4_residual_after_actual, col_q4_transfer_econ, col_q4_total, col_fact_year, col_pay_year, col_economy_year, col_internal_order, col_cs_total, col_cs_counterparty, col_cs_deadline, col_cs_comment, col_cs_future_y1, col_cs_future_y2, col_cs_other_ssp, col_al_contract_ref, col_al_purpose, col_al_order, col_al_property, col_ca_approved, col_ca_protocol, col_ca_note, col_ckk_ceiling, col_ckk_rf_sched, col_ckk_deadline, col_ckk_proc_plan, col_ckk_proc_meth, col_ckk_comment, col_cd_addenda, col_cd_exp_q1, col_cd_exp_q2, col_cd_exp_q3, col_cd_exp_q4, col_cd_rf_sched, col_cd_exchange_rate, col_cd_amount_foreign, col_q1_adj_rf, col_q1_pay_ho, col_q1_pay_rf, col_q2_adj_rf, col_q2_pay_ho, col_q2_pay_rf, col_q3_adj_rf, col_q3_pay_ho, col_q3_pay_rf, col_q4_adj_rf, col_q4_pay_ho, col_q4_pay_rf, _sort_path, _k) + JOIN sk ON sk.k = sub._k + ORDER BY sk.rnk; +END; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.v_form1_sheet_sections(p_form_id integer, p_sheet character varying, p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) + RETURNS TABLE(row_type character varying, depth integer, line_id integer, col_b_year integer, col_c_section character varying, col_d_item_id character varying, col_e_num_group character varying, col_f_name character varying, col_g_internal_order character varying, col_h_plan_q1 numeric, col_i_plan_q2 numeric, col_j_plan_q3 numeric, col_k_plan_q4 numeric, col_l_plan_year numeric, col_m_plan_comment character varying, col_n_cs_total numeric, col_o_cs_counterparty character varying, col_p_cs_deadline character varying, col_q_cs_comment character varying, col_r_cs_future_y1 numeric, col_s_cs_future_y2 numeric, col_t_cs_other_ssp numeric, col_v_al_order character varying, col_w_al_property character varying, col_y_seq_q1 numeric, col_z_seq_q2 numeric, col_aa_seq_q3 numeric, col_ab_seq_q4 numeric, col_ac_seq_year numeric, col_ad_seq_justification character varying, col_af_res_q1 numeric, col_ag_res_q2 numeric, col_ah_res_q3 numeric, col_ai_res_q4 numeric, col_aj_res_year numeric, col_ak_res_justification character varying, col_am_approved_q1 numeric, col_an_approved_q2 numeric, col_ao_approved_q3 numeric, col_ap_approved_q4 numeric, col_aq_approved_year numeric, col_as_ca_approved numeric, col_at_ca_protocol character varying, col_au_ca_note character varying, col_aw_ckk_ceiling numeric, col_ax_ckk_exp_q1 numeric, col_ay_ckk_exp_q2 numeric, col_az_ckk_exp_q3 numeric, col_ba_ckk_exp_q4 numeric, col_bb_ckk_rf_sched character varying, col_bc_ckk_deadline character varying, col_bd_ckk_proc_plan character varying, col_be_ckk_proc_meth character varying, col_bf_ckk_comment character varying, col_bh_cd_counterparty character varying, col_bi_cd_reference character varying, col_bj_cd_addenda character varying, col_bk_cd_subject character varying, col_bl_cd_currency character varying, col_bm_cd_ceiling numeric, col_bn_cd_exp_q1 numeric, col_bo_cd_exp_q2 numeric, col_bp_cd_exp_q3 numeric, col_bq_cd_exp_q4 numeric, col_br_cd_rf_sched character varying, col_bs_cd_vat character varying, col_bt_cd_rate numeric, col_bu_cd_amount_fx numeric, col_bv_cd_deadline character varying, col_bw_cd_scheme character varying, col_bx_cd_act character varying, col_by_cd_comment character varying, col_ca_q1_adj_current numeric, col_cb_q1_adj_ssp numeric, col_cc_q1_adj_rf numeric, col_cd_q1_adj_reserve numeric, col_ce_q1_adj_comment character varying, col_cf_q1_corrected_plan numeric, col_ch_q1_pay_date date, col_ci_q1_pay_amount numeric, col_cj_q1_pay_ho numeric, col_ck_q1_pay_rf numeric, col_cl_q1_pay_comment character varying, col_cm_q1_pay_act character varying, col_co_q1_booking numeric, col_cp_q1_actual_m1 numeric, col_cq_q1_actual_m2 numeric, col_cr_q1_actual_m3 numeric, col_cs_q1_actual_quarter numeric, col_ct_q1_rem_booking numeric, col_cu_q1_rem_actual numeric, col_cw_q1_trans_q2 numeric, col_cx_q1_trans_q3 numeric, col_cy_q1_trans_q4 numeric, col_cz_q1_economy numeric, col_da_q1_total numeric, col_dc_q2_rev_eco numeric, col_dd_q2_rev_item numeric, col_de_q2_rev_inc numeric, col_df_q2_rev_seq numeric, col_dg_q2_rev_comment character varying, col_dh_q2_new_plan numeric, col_dj_q2_adj_current numeric, col_dk_q2_adj_ssp numeric, col_dl_q2_adj_rf numeric, col_dm_q2_adj_reserve numeric, col_dn_q2_adj_comment character varying, col_do_q2_corrected_plan numeric, col_dq_q2_pay_date date, col_dr_q2_pay_amount numeric, col_ds_q2_pay_ho numeric, col_dt_q2_pay_rf numeric, col_du_q2_pay_comment character varying, col_dv_q2_pay_act character varying, col_dx_q2_booking numeric, col_dy_q2_actual_m1 numeric, col_dz_q2_actual_m2 numeric, col_ea_q2_actual_m3 numeric, col_eb_q2_actual_quarter numeric, col_ec_q2_rem_booking numeric, col_ed_q2_rem_actual numeric, col_ef_q2_trans_q3 numeric, col_eg_q2_trans_q4 numeric, col_eh_q2_economy numeric, col_ei_q2_total numeric, col_ek_q3_rev_eco numeric, col_el_q3_rev_item numeric, col_em_q3_rev_inc numeric, col_en_q3_rev_seq numeric, col_eo_q3_rev_comment character varying, col_ep_q3_new_plan numeric, col_er_q3_adj_current numeric, col_es_q3_adj_ssp numeric, col_et_q3_adj_rf numeric, col_eu_q3_adj_reserve numeric, col_ev_q3_adj_comment character varying, col_ew_q3_corrected_plan numeric, col_ey_q3_pay_date date, col_ez_q3_pay_amount numeric, col_fa_q3_pay_ho numeric, col_fb_q3_pay_rf numeric, col_fc_q3_pay_comment character varying, col_fd_q3_pay_act character varying, col_ff_q3_booking numeric, col_fg_q3_actual_m1 numeric, col_fh_q3_actual_m2 numeric, col_fi_q3_actual_m3 numeric, col_fj_q3_actual_quarter numeric, col_fk_q3_rem_booking numeric, col_fl_q3_rem_actual numeric, col_fn_q3_trans_q4 numeric, col_fo_q3_economy numeric, col_fp_q3_total numeric, col_fr_q4_rev_eco numeric, col_fs_q4_rev_item numeric, col_ft_q4_rev_inc numeric, col_fu_q4_rev_seq numeric, col_fv_q4_rev_comment character varying, col_fw_q4_new_plan numeric, col_fy_q4_adj_current numeric, col_fz_q4_adj_ssp numeric, col_ga_q4_adj_rf numeric, col_gb_q4_adj_reserve numeric, col_gc_q4_adj_comment character varying, col_gd_q4_corrected_plan numeric, col_gf_q4_pay_date date, col_gg_q4_pay_amount numeric, col_gh_q4_pay_ho numeric, col_gi_q4_pay_rf numeric, col_gj_q4_pay_comment character varying, col_gk_q4_pay_act character varying, col_gm_q4_booking numeric, col_gn_q4_actual_m1 numeric, col_go_q4_actual_m2 numeric, col_gp_q4_actual_m3 numeric, col_gq_q4_actual_quarter numeric, col_gr_q4_actual_spod numeric, col_gs_q4_rem_booking numeric, col_gt_q4_rem_actual numeric, col_gv_q4_economy numeric, col_gw_q4_total numeric, col_gz_fact_year numeric, col_hb_pay_year numeric, _sort_path integer[], _sort_rank bigint) + LANGUAGE plpgsql + STABLE + SET jit TO 'off' + SET search_path TO 'v3', 'pg_catalog' +AS $function$ +#variable_conflict use_column +DECLARE + v_year INT; + s_plan BOOL; s_cs BOOL; s_al BOOL; s_seq BOOL; s_res BOOL; + s_appr BOOL; s_ca BOOL; s_ckk BOOL; s_cd BOOL; + s_q1 BOOL; s_q2 BOOL; s_q3 BOOL; s_q4 BOOL; s_tot BOOL; + s_any_q BOOL; + s_need_ap BOOL; + s_need_bk BOOL; + v_focus_nodes INT[]; -- AURORA-1850: узлы фокуса (путь статей строк фокуса ∩ tw); NULL = весь лист + v_focus_eids INT[]; -- AURORA-1850: объединение desc_ids узлов фокуса +BEGIN + SELECT bf.year INTO v_year FROM budget_form bf WHERE bf.id = p_form_id; + + s_plan := p_sections IS NULL OR 'plan' = ANY(p_sections); + s_cs := p_sections IS NULL OR 'contract_summary' = ANY(p_sections); + s_al := p_sections IS NULL OR 'allocation' = ANY(p_sections); + s_seq := p_sections IS NULL OR 'sequestration' = ANY(p_sections); + s_res := p_sections IS NULL OR 'reserve' = ANY(p_sections); + s_appr := p_sections IS NULL OR 'approved' = ANY(p_sections); + s_ca := p_sections IS NULL OR 'collegial' = ANY(p_sections); + s_ckk := p_sections IS NULL OR 'ckk' = ANY(p_sections); + s_cd := p_sections IS NULL OR 'contract_detail' = ANY(p_sections); + s_q1 := p_sections IS NULL OR 'q1' = ANY(p_sections); + s_q2 := p_sections IS NULL OR 'q2' = ANY(p_sections); + s_q3 := p_sections IS NULL OR 'q3' = ANY(p_sections); + s_q4 := p_sections IS NULL OR 'q4' = ANY(p_sections); + s_tot := p_sections IS NULL OR 'totals' = ANY(p_sections); + s_any_q := s_q1 OR s_q2 OR s_q3 OR s_q4 OR s_tot; + s_need_ap := s_plan OR s_appr OR s_q1 OR s_q2 OR s_q3 OR s_q4; + s_need_bk := s_q1 OR s_q2 OR s_q3 OR s_q4; + + -- Фокус (D1): NULL = весь лист, '{}' = пустой результат. COALESCE обязателен: + -- пустой фокус не должен превратиться в NULL и провалиться в полную сборку. + -- Узлы фокуса берутся из budget_line БЕЗ фильтра direction (tw тоже без него). + IF p_focus_lines IS NOT NULL THEN + WITH fp AS ( + SELECT v3._expense_item_path_set( + (SELECT array_agg(DISTINCT bl.expense_item_id) + FROM v3.budget_line bl + WHERE bl.id = ANY(p_focus_lines))) AS ids + ), + fn AS ( + SELECT t.id, t.desc_ids + FROM v3.mv_expense_item_tree t + JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id + JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code + WHERE t.sheet = p_sheet + AND t.id = ANY(COALESCE((SELECT fp.ids FROM fp), '{}'::int[])) + ) + SELECT COALESCE((SELECT array_agg(fn.id) FROM fn), '{}'::int[]), + COALESCE((SELECT array_agg(DISTINCT d) FROM fn, unnest(fn.desc_ids) AS d), '{}'::int[]) + INTO v_focus_nodes, v_focus_eids; + END IF; + + RETURN QUERY + WITH + tw AS ( + SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, + t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids, + p.parent_item_id AS grandparent_item_id + FROM mv_expense_item_tree t + LEFT JOIN mv_expense_item_tree p ON p.id = t.parent_id + JOIN expense_item_form_type eft ON eft.expense_item_id = t.id + JOIN budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code + WHERE t.sheet = p_sheet + ), + + page AS ( + SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.internal_order AS io, + bl.name AS bname + FROM budget_line bl + JOIN expense_item ei ON ei.id = bl.expense_item_id + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet + AND (p_direction IS NULL OR bl.direction IS NULL OR bl.direction = p_direction) + ), + + tw_f AS ( + SELECT * FROM tw WHERE p_focus_lines IS NULL OR tw.id = ANY(v_focus_nodes) + ), + page_f AS ( + SELECT * FROM page WHERE p_focus_lines IS NULL OR page.lid = ANY(p_focus_lines) + ), + -- Скелет листа (D2): ключи всех узлов tw и всех строк page JOIN tw (page уже с фильтром direction), + -- без jsonb и сумм. Ранг одинаков в обоих режимах; tie-break D6: узел раньше строки. + sk AS ( + SELECT n.k, + ROW_NUMBER() OVER (ORDER BY n._sort, n.lid NULLS FIRST) AS rnk + FROM ( + SELECT -t0.id::BIGINT AS k, NULL::INT AS lid, t0.path AS _sort FROM tw t0 + UNION ALL + SELECT pg0.lid::BIGINT, pg0.lid::INT, t1.path || ARRAY[pg0.lid::INT] + FROM page pg0 JOIN tw t1 ON t1.id = pg0.eid + ) n + ), + + jp AS (SELECT p.* FROM plan p JOIN page_f pg ON p.line_id = pg.lid WHERE s_plan), + jcs AS (SELECT cs.* FROM contract_summary cs JOIN page_f pg ON cs.line_id = pg.lid WHERE s_cs), + jal AS (SELECT al.* FROM allocation al JOIN page_f pg ON al.line_id = pg.lid WHERE s_al), + jsd AS (SELECT sd.* FROM sequestration sd JOIN page_f pg ON sd.line_id = pg.lid WHERE s_seq AND sd.actor='DFIP'), + jr AS (SELECT r.* FROM reserve r JOIN page_f pg ON r.line_id = pg.lid WHERE s_res), + jca AS (SELECT ca.* FROM collegial_approval ca JOIN page_f pg ON ca.line_id = pg.lid WHERE s_ca), + jck AS (SELECT ck.* FROM ckk ck JOIN page_f pg ON ck.line_id = pg.lid WHERE s_ckk), + jcd AS (SELECT cd.* FROM contract_detail cd JOIN page_f pg ON cd.line_id = pg.lid WHERE s_cd), + jq1 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE s_q1 AND blq.quarter = 1), + jq2 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE s_q2 AND blq.quarter = 2), + jq3 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE s_q3 AND blq.quarter = 3), + jq4 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE (s_q4 OR s_tot) AND blq.quarter = 4), + jtot AS ( + SELECT blq.line_id AS tlid, + SUM(CASE WHEN blq.quarter=1 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq1, + SUM(CASE WHEN blq.quarter=2 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq2, + SUM(CASE WHEN blq.quarter=3 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq3, + SUM(CASE WHEN blq.quarter=4 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0)+COALESCE(blq.actual_spod,0) END) AS tot_aq4, + SUM(CASE WHEN blq.quarter=1 THEN blq.payment_amount END) AS tot_pa1, + SUM(CASE WHEN blq.quarter=2 THEN blq.payment_amount END) AS tot_pa2, + SUM(CASE WHEN blq.quarter=3 THEN blq.payment_amount END) AS tot_pa3, + SUM(CASE WHEN blq.quarter=4 THEN blq.payment_amount END) AS tot_pa4 + FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid + WHERE s_tot + GROUP BY blq.line_id + ), + + input_base AS ( + SELECT + pg.lid, pg.eid, pg.io, pg.bname, + CASE + WHEN t.depth < 3 THEN t.item_id + WHEN t.depth = 3 THEN t.parent_item_id + WHEN t.depth = 4 THEN t.grandparent_item_id + END AS sc, + t.item_id AS ic, + t.num_group_id AS ng, t.name AS ename, + COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2, + COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4, + p.comment AS pcmt, + COALESCE(sd.adj_q1,0) AS sq1, COALESCE(sd.adj_q2,0) AS sq2, + COALESCE(sd.adj_q3,0) AS sq3, COALESCE(sd.adj_q4,0) AS sq4, + sd.justification AS sjust, + COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2, + COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4, + r.justification AS rjust, + cs.*, al.internal_order AS al_io, al.property_object AS al_po, + ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_prot, ca.note AS ca_note, + ck.ceiling_amount AS ckk_ceil, + COALESCE(ck.expenses_q1,0) AS ckk1, COALESCE(ck.expenses_q2,0) AS ckk2, + COALESCE(ck.expenses_q3,0) AS ckk3, COALESCE(ck.expenses_q4,0) AS ckk4, + ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl, + ck.procurement_plan AS ckk_pp, ck.procurement_method AS ckk_pm, ck.comment AS ckk_cmt, + cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add, + cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil, + COALESCE(cd.expenses_q1,0) AS cdq1, COALESCE(cd.expenses_q2,0) AS cdq2, + COALESCE(cd.expenses_q3,0) AS cdq3, COALESCE(cd.expenses_q4,0) AS cdq4, + cd.rf_schedule AS cd_rf, cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_rate, + cd.amount_foreign AS cd_fx, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch, + cd.act AS cd_act, cd.comment AS cd_cmt2, + q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_ar, q1.adj_reserve AS q1_arv, + q1.adj_comment AS q1_acmt, q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa, + q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, + q1.payment_comment AS q1_pcmt, q1.payment_act AS q1_pact, + q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3, + q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4, + q2.plan_revision_eco_change AS q2_reco, q2.plan_revision_item_adj AS q2_ritm, + q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq, + q2.plan_revision_comment AS q2_rcmt, + q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_ar, q2.adj_reserve AS q2_arv, + q2.adj_comment AS q2_acmt, q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa, + q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf, + q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact, + q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3, + q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, + q3.plan_revision_eco_change AS q3_reco, q3.plan_revision_item_adj AS q3_ritm, + q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq, + q3.plan_revision_comment AS q3_rcmt, + q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_ar, q3.adj_reserve AS q3_arv, + q3.adj_comment AS q3_acmt, q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa, + q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf, + q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact, + q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3, + q3.transfer_to_q4 AS q3_tq4, + q4.plan_revision_eco_change AS q4_reco, q4.plan_revision_item_adj AS q4_ritm, + q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq, + q4.plan_revision_comment AS q4_rcmt, + q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_ar, q4.adj_reserve AS q4_arv, + q4.adj_comment AS q4_acmt, q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa, + q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf, + q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact, + q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, + q4.actual_spod AS q4_spod, + tot.tot_aq1, tot.tot_aq2, tot.tot_aq3, tot.tot_aq4, + tot.tot_pa1, tot.tot_pa2, tot.tot_pa3, tot.tot_pa4, + CASE WHEN COALESCE(cd.expenses_q1,0)>0 THEN cd.expenses_q1 ELSE ck.expenses_q1 END AS bk1, + CASE WHEN COALESCE(cd.expenses_q2,0)>0 THEN cd.expenses_q2 ELSE ck.expenses_q2 END AS bk2, + CASE WHEN COALESCE(cd.expenses_q3,0)>0 THEN cd.expenses_q3 ELSE ck.expenses_q3 END AS bk3, + CASE WHEN COALESCE(cd.expenses_q4,0)>0 THEN cd.expenses_q4 ELSE ck.expenses_q4 END AS bk4, + COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1, + COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2, + COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3, + COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4, + t.path AS tree_path + FROM page_f pg + JOIN tw t ON t.id = pg.eid + LEFT JOIN jp p ON p.line_id = pg.lid + LEFT JOIN jcs cs ON cs.line_id = pg.lid + LEFT JOIN jal al ON al.line_id = pg.lid + LEFT JOIN jsd sd ON sd.line_id = pg.lid + LEFT JOIN jr r ON r.line_id = pg.lid + LEFT JOIN jca ca ON ca.line_id = pg.lid + LEFT JOIN jck ck ON ck.line_id = pg.lid + LEFT JOIN jcd cd ON cd.line_id = pg.lid + LEFT JOIN jq1 q1 ON q1.line_id = pg.lid + LEFT JOIN jq2 q2 ON q2.line_id = pg.lid + LEFT JOIN jq3 q3 ON q3.line_id = pg.lid + LEFT JOIN jq4 q4 ON q4.line_id = pg.lid + LEFT JOIN jtot tot ON tot.tlid = pg.lid + ), + enriched AS ( + SELECT b.*, + b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_ar,0)+COALESCE(b.q1_arv,0) AS cp1, + COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1, + b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_reco,0)+COALESCE(b.q2_ritm,0)+COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) AS np2, + COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2, + b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_reco,0)+COALESCE(b.q3_ritm,0)+COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) AS np3, + COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3, + b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_reco,0)+COALESCE(b.q4_ritm,0)+COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) AS np4, + COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0) AS aq4_no_spod, + COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4 + FROM input_base b + ), + final_input AS ( + SELECT e.*, + e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_ar,0)+COALESCE(e.q2_arv,0) AS cp2, + e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_ar,0)+COALESCE(e.q3_arv,0) AS cp3, + e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_ar,0)+COALESCE(e.q4_arv,0) AS cp4 + FROM enriched e + ), + + agg AS ( + SELECT bl.expense_item_id AS eid, + SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4, + SUM(sd.adj_q1) AS ss1, SUM(sd.adj_q2) AS ss2, SUM(sd.adj_q3) AS ss3, SUM(sd.adj_q4) AS ss4, + SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4, + SUM(ca.approved_amount) AS sca, + SUM(ck.ceiling_amount) AS sckc, + SUM(ck.expenses_q1) AS sck1, SUM(ck.expenses_q2) AS sck2, SUM(ck.expenses_q3) AS sck3, SUM(ck.expenses_q4) AS sck4, + SUM(cd.ceiling_amount) AS scdc, + SUM(cd.expenses_q1) AS scd1, SUM(cd.expenses_q2) AS scd2, SUM(cd.expenses_q3) AS scd3, SUM(cd.expenses_q4) AS scd4, + SUM(cs.total_amount) AS scst, SUM(cs.future_payments_y1) AS sfy1, SUM(cs.future_payments_y2) AS sfy2, + SUM(cs.other_ssp_amount) AS sossp + FROM budget_line bl + JOIN expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN plan p ON p.line_id = bl.id AND s_need_ap + LEFT JOIN contract_summary cs ON cs.line_id = bl.id AND s_cs + LEFT JOIN sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP' AND s_need_ap + LEFT JOIN reserve r ON r.line_id = bl.id AND s_need_ap + LEFT JOIN collegial_approval ca ON ca.line_id = bl.id AND s_ca + LEFT JOIN ckk ck ON ck.line_id = bl.id AND (s_ckk OR s_need_bk) + LEFT JOIN contract_detail cd ON cd.line_id = bl.id AND (s_cd OR s_need_bk) + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + AND (s_need_ap OR s_cs OR s_ca OR s_ckk OR s_cd OR s_need_bk) + GROUP BY bl.expense_item_id + ), + aq1 AS ( + SELECT bl.expense_item_id AS eid, + SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, + SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, + SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, + SUM(blq.transfer_to_q2) AS tq2, SUM(blq.transfer_to_q3) AS tq3, SUM(blq.transfer_to_q4) AS tq4 + FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 1 + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q1 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id + ), + aq2 AS ( + SELECT bl.expense_item_id AS eid, + SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm, + SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq, + SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, + SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, + SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, + SUM(blq.transfer_to_q3) AS tq3, SUM(blq.transfer_to_q4) AS tq4 + FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 2 + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q2 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id + ), + aq3 AS ( + SELECT bl.expense_item_id AS eid, + SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm, + SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq, + SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, + SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, + SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, + SUM(blq.transfer_to_q4) AS tq4 + FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 3 + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q3 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id + ), + aq4 AS ( + SELECT bl.expense_item_id AS eid, + SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm, + SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq, + SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, + SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, + SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, + SUM(blq.actual_spod) AS spod + FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 4 + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND (s_q4 OR s_tot) AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id + ), + atot AS ( + SELECT bl.expense_item_id AS eid, + SUM(CASE WHEN blq.quarter=1 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq1, + SUM(CASE WHEN blq.quarter=2 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq2, + SUM(CASE WHEN blq.quarter=3 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq3, + SUM(CASE WHEN blq.quarter=4 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0)+COALESCE(blq.actual_spod,0) END) AS fq4, + SUM(blq.payment_amount) AS pay + FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id + WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_tot AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) + AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) + GROUP BY bl.expense_item_id + ), + tw_agg AS ( + SELECT tw.id, + SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4, + SUM(a.ss1) AS ss1, SUM(a.ss2) AS ss2, SUM(a.ss3) AS ss3, SUM(a.ss4) AS ss4, + SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4, + SUM(a.sca) AS sca, + SUM(a.sckc) AS sckc, SUM(a.sck1) AS sck1, SUM(a.sck2) AS sck2, SUM(a.sck3) AS sck3, SUM(a.sck4) AS sck4, + SUM(a.scdc) AS scdc, SUM(a.scd1) AS scd1, SUM(a.scd2) AS scd2, SUM(a.scd3) AS scd3, SUM(a.scd4) AS scd4, + SUM(a.scst) AS scst, SUM(a.sfy1) AS sfy1, SUM(a.sfy2) AS sfy2, SUM(a.sossp) AS sossp, + SUM(CASE WHEN COALESCE(a.scd1,0)>0 THEN a.scd1 ELSE a.sck1 END) AS bk1, + SUM(CASE WHEN COALESCE(a.scd2,0)>0 THEN a.scd2 ELSE a.sck2 END) AS bk2, + SUM(CASE WHEN COALESCE(a.scd3,0)>0 THEN a.scd3 ELSE a.sck3 END) AS bk3, + SUM(CASE WHEN COALESCE(a.scd4,0)>0 THEN a.scd4 ELSE a.sck4 END) AS bk4 + FROM tw_f tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids) + GROUP BY tw.id + ), + tw_aq1 AS ( + SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4 + FROM tw_f tw LEFT JOIN aq1 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id + ), + tw_aq2 AS ( + SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq, + SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4 + FROM tw_f tw LEFT JOIN aq2 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id + ), + tw_aq3 AS ( + SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq, + SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.tq4) AS tq4 + FROM tw_f tw LEFT JOIN aq3 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id + ), + tw_aq4 AS ( + SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq, + SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, + SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, + SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, + SUM(b.spod) AS spod + FROM tw_f tw LEFT JOIN aq4 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id + ), + tw_atot AS ( + SELECT tw.id, SUM(b.fq1) AS fq1, SUM(b.fq2) AS fq2, SUM(b.fq3) AS fq3, SUM(b.fq4) AS fq4, + SUM(b.pay) AS pay + FROM tw_f tw LEFT JOIN atot b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id + ) + + SELECT sub.row_type, sub.depth, sub.line_id, sub.col_b_year, sub.col_c_section, sub.col_d_item_id, sub.col_e_num_group, sub.col_f_name, sub.col_g_internal_order, sub.col_h_plan_q1, sub.col_i_plan_q2, sub.col_j_plan_q3, sub.col_k_plan_q4, sub.col_l_plan_year, sub.col_m_plan_comment, sub.col_n_cs_total, sub.col_o_cs_counterparty, sub.col_p_cs_deadline, sub.col_q_cs_comment, sub.col_r_cs_future_y1, sub.col_s_cs_future_y2, sub.col_t_cs_other_ssp, sub.col_v_al_order, sub.col_w_al_property, sub.col_y_seq_q1, sub.col_z_seq_q2, sub.col_aa_seq_q3, sub.col_ab_seq_q4, sub.col_ac_seq_year, sub.col_ad_seq_justification, sub.col_af_res_q1, sub.col_ag_res_q2, sub.col_ah_res_q3, sub.col_ai_res_q4, sub.col_aj_res_year, sub.col_ak_res_justification, sub.col_am_approved_q1, sub.col_an_approved_q2, sub.col_ao_approved_q3, sub.col_ap_approved_q4, sub.col_aq_approved_year, sub.col_as_ca_approved, sub.col_at_ca_protocol, sub.col_au_ca_note, sub.col_aw_ckk_ceiling, sub.col_ax_ckk_exp_q1, sub.col_ay_ckk_exp_q2, sub.col_az_ckk_exp_q3, sub.col_ba_ckk_exp_q4, sub.col_bb_ckk_rf_sched, sub.col_bc_ckk_deadline, sub.col_bd_ckk_proc_plan, sub.col_be_ckk_proc_meth, sub.col_bf_ckk_comment, sub.col_bh_cd_counterparty, sub.col_bi_cd_reference, sub.col_bj_cd_addenda, sub.col_bk_cd_subject, sub.col_bl_cd_currency, sub.col_bm_cd_ceiling, sub.col_bn_cd_exp_q1, sub.col_bo_cd_exp_q2, sub.col_bp_cd_exp_q3, sub.col_bq_cd_exp_q4, sub.col_br_cd_rf_sched, sub.col_bs_cd_vat, sub.col_bt_cd_rate, sub.col_bu_cd_amount_fx, sub.col_bv_cd_deadline, sub.col_bw_cd_scheme, sub.col_bx_cd_act, sub.col_by_cd_comment, sub.col_ca_q1_adj_current, sub.col_cb_q1_adj_ssp, sub.col_cc_q1_adj_rf, sub.col_cd_q1_adj_reserve, sub.col_ce_q1_adj_comment, sub.col_cf_q1_corrected_plan, sub.col_ch_q1_pay_date, sub.col_ci_q1_pay_amount, sub.col_cj_q1_pay_ho, sub.col_ck_q1_pay_rf, sub.col_cl_q1_pay_comment, sub.col_cm_q1_pay_act, sub.col_co_q1_booking, sub.col_cp_q1_actual_m1, sub.col_cq_q1_actual_m2, sub.col_cr_q1_actual_m3, sub.col_cs_q1_actual_quarter, sub.col_ct_q1_rem_booking, sub.col_cu_q1_rem_actual, sub.col_cw_q1_trans_q2, sub.col_cx_q1_trans_q3, sub.col_cy_q1_trans_q4, sub.col_cz_q1_economy, sub.col_da_q1_total, sub.col_dc_q2_rev_eco, sub.col_dd_q2_rev_item, sub.col_de_q2_rev_inc, sub.col_df_q2_rev_seq, sub.col_dg_q2_rev_comment, sub.col_dh_q2_new_plan, sub.col_dj_q2_adj_current, sub.col_dk_q2_adj_ssp, sub.col_dl_q2_adj_rf, sub.col_dm_q2_adj_reserve, sub.col_dn_q2_adj_comment, sub.col_do_q2_corrected_plan, sub.col_dq_q2_pay_date, sub.col_dr_q2_pay_amount, sub.col_ds_q2_pay_ho, sub.col_dt_q2_pay_rf, sub.col_du_q2_pay_comment, sub.col_dv_q2_pay_act, sub.col_dx_q2_booking, sub.col_dy_q2_actual_m1, sub.col_dz_q2_actual_m2, sub.col_ea_q2_actual_m3, sub.col_eb_q2_actual_quarter, sub.col_ec_q2_rem_booking, sub.col_ed_q2_rem_actual, sub.col_ef_q2_trans_q3, sub.col_eg_q2_trans_q4, sub.col_eh_q2_economy, sub.col_ei_q2_total, sub.col_ek_q3_rev_eco, sub.col_el_q3_rev_item, sub.col_em_q3_rev_inc, sub.col_en_q3_rev_seq, sub.col_eo_q3_rev_comment, sub.col_ep_q3_new_plan, sub.col_er_q3_adj_current, sub.col_es_q3_adj_ssp, sub.col_et_q3_adj_rf, sub.col_eu_q3_adj_reserve, sub.col_ev_q3_adj_comment, sub.col_ew_q3_corrected_plan, sub.col_ey_q3_pay_date, sub.col_ez_q3_pay_amount, sub.col_fa_q3_pay_ho, sub.col_fb_q3_pay_rf, sub.col_fc_q3_pay_comment, sub.col_fd_q3_pay_act, sub.col_ff_q3_booking, sub.col_fg_q3_actual_m1, sub.col_fh_q3_actual_m2, sub.col_fi_q3_actual_m3, sub.col_fj_q3_actual_quarter, sub.col_fk_q3_rem_booking, sub.col_fl_q3_rem_actual, sub.col_fn_q3_trans_q4, sub.col_fo_q3_economy, sub.col_fp_q3_total, sub.col_fr_q4_rev_eco, sub.col_fs_q4_rev_item, sub.col_ft_q4_rev_inc, sub.col_fu_q4_rev_seq, sub.col_fv_q4_rev_comment, sub.col_fw_q4_new_plan, sub.col_fy_q4_adj_current, sub.col_fz_q4_adj_ssp, sub.col_ga_q4_adj_rf, sub.col_gb_q4_adj_reserve, sub.col_gc_q4_adj_comment, sub.col_gd_q4_corrected_plan, sub.col_gf_q4_pay_date, sub.col_gg_q4_pay_amount, sub.col_gh_q4_pay_ho, sub.col_gi_q4_pay_rf, sub.col_gj_q4_pay_comment, sub.col_gk_q4_pay_act, sub.col_gm_q4_booking, sub.col_gn_q4_actual_m1, sub.col_go_q4_actual_m2, sub.col_gp_q4_actual_m3, sub.col_gq_q4_actual_quarter, sub.col_gr_q4_actual_spod, sub.col_gs_q4_rem_booking, sub.col_gt_q4_rem_actual, sub.col_gv_q4_economy, sub.col_gw_q4_total, sub.col_gz_fact_year, sub.col_hb_pay_year, sub._sort_path, sk.rnk + FROM ( + SELECT + 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid, + v_year, f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.io, + CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END, + CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END, + CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END, + CASE WHEN s_cs THEN f.total_amount END, CASE WHEN s_cs THEN f.counterparty END, + CASE WHEN s_cs THEN f.deadline END, CASE WHEN s_cs THEN f.comment END, + CASE WHEN s_cs THEN f.future_payments_y1 END, CASE WHEN s_cs THEN f.future_payments_y2 END, + CASE WHEN s_cs THEN f.other_ssp_amount END, + CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_po END, + CASE WHEN s_seq THEN f.sq1 END, CASE WHEN s_seq THEN f.sq2 END, + CASE WHEN s_seq THEN f.sq3 END, CASE WHEN s_seq THEN f.sq4 END, + CASE WHEN s_seq THEN f.sq1+f.sq2+f.sq3+f.sq4 END, CASE WHEN s_seq THEN f.sjust END, + CASE WHEN s_res THEN f.rq1 END, CASE WHEN s_res THEN f.rq2 END, + CASE WHEN s_res THEN f.rq3 END, CASE WHEN s_res THEN f.rq4 END, + CASE WHEN s_res THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_res THEN f.rjust END, + CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END, + CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END, + CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END, + CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_prot END, CASE WHEN s_ca THEN f.ca_note END, + CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk1 END, CASE WHEN s_ckk THEN f.ckk2 END, + CASE WHEN s_ckk THEN f.ckk3 END, CASE WHEN s_ckk THEN f.ckk4 END, + CASE WHEN s_ckk THEN f.ckk_rf END, CASE WHEN s_ckk THEN f.ckk_dl END, + CASE WHEN s_ckk THEN f.ckk_pp END, CASE WHEN s_ckk THEN f.ckk_pm END, CASE WHEN s_ckk THEN f.ckk_cmt END, + CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END, CASE WHEN s_cd THEN f.cd_add END, + CASE WHEN s_cd THEN f.cd_subj END, CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END, + CASE WHEN s_cd THEN f.cdq1 END, CASE WHEN s_cd THEN f.cdq2 END, + CASE WHEN s_cd THEN f.cdq3 END, CASE WHEN s_cd THEN f.cdq4 END, + CASE WHEN s_cd THEN f.cd_rf END, CASE WHEN s_cd THEN f.cd_vat END, + CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END, + CASE WHEN s_cd THEN f.cd_dl END, CASE WHEN s_cd THEN f.cd_sch END, + CASE WHEN s_cd THEN f.cd_act END, CASE WHEN s_cd THEN f.cd_cmt2 END, + CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, + CASE WHEN s_q1 THEN f.q1_ar END, CASE WHEN s_q1 THEN f.q1_arv END, + CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END, + CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END, + CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, + CASE WHEN s_q1 THEN f.q1_pcmt END, CASE WHEN s_q1 THEN f.q1_pact END, + CASE WHEN s_q1 THEN COALESCE(f.bk1,0) END, + CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END, + CASE WHEN s_q1 THEN f.aq1 END, + CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.bk1,0) END, + CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, + CASE WHEN s_q1 THEN f.q1_tq2 END, CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END, + CASE WHEN s_q1 THEN f.cp1 - f.aq1 - COALESCE(f.q1_tq2,0) - COALESCE(f.q1_tq3,0) - COALESCE(f.q1_tq4,0) END, + CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, + CASE WHEN s_q2 THEN f.q2_reco END, CASE WHEN s_q2 THEN f.q2_ritm END, + CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END, + CASE WHEN s_q2 THEN f.q2_rcmt END, CASE WHEN s_q2 THEN f.np2 END, + CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, + CASE WHEN s_q2 THEN f.q2_ar END, CASE WHEN s_q2 THEN f.q2_arv END, + CASE WHEN s_q2 THEN f.q2_acmt END, CASE WHEN s_q2 THEN f.cp2 END, + CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END, + CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END, + CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END, + CASE WHEN s_q2 THEN COALESCE(f.bk2,0) END, + CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END, + CASE WHEN s_q2 THEN f.aq2 END, + CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.bk2,0) END, + CASE WHEN s_q2 THEN f.cp2 - f.aq2 END, + CASE WHEN s_q2 THEN f.q2_tq3 END, CASE WHEN s_q2 THEN f.q2_tq4 END, + CASE WHEN s_q2 THEN f.cp2 - f.aq2 - COALESCE(f.q2_tq3,0) - COALESCE(f.q2_tq4,0) END, + CASE WHEN s_q2 THEN f.cp2 - f.aq2 END, + CASE WHEN s_q3 THEN f.q3_reco END, CASE WHEN s_q3 THEN f.q3_ritm END, + CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END, + CASE WHEN s_q3 THEN f.q3_rcmt END, CASE WHEN s_q3 THEN f.np3 END, + CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, + CASE WHEN s_q3 THEN f.q3_ar END, CASE WHEN s_q3 THEN f.q3_arv END, + CASE WHEN s_q3 THEN f.q3_acmt END, CASE WHEN s_q3 THEN f.cp3 END, + CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END, + CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END, + CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END, + CASE WHEN s_q3 THEN COALESCE(f.bk3,0) END, + CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END, + CASE WHEN s_q3 THEN f.aq3 END, + CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.bk3,0) END, + CASE WHEN s_q3 THEN f.cp3 - f.aq3 END, + CASE WHEN s_q3 THEN f.q3_tq4 END, + CASE WHEN s_q3 THEN f.cp3 - f.aq3 - COALESCE(f.q3_tq4,0) END, + CASE WHEN s_q3 THEN f.cp3 - f.aq3 END, + CASE WHEN s_q4 THEN f.q4_reco END, CASE WHEN s_q4 THEN f.q4_ritm END, + CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END, + CASE WHEN s_q4 THEN f.q4_rcmt END, CASE WHEN s_q4 THEN f.np4 END, + CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, + CASE WHEN s_q4 THEN f.q4_ar END, CASE WHEN s_q4 THEN f.q4_arv END, + CASE WHEN s_q4 THEN f.q4_acmt END, CASE WHEN s_q4 THEN f.cp4 END, + CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END, + CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END, + CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END, + CASE WHEN s_q4 THEN COALESCE(f.bk4,0) END, + CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END, + CASE WHEN s_q4 THEN f.aq4_no_spod END, + CASE WHEN s_q4 THEN f.q4_spod END, + CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.bk4,0) END, + CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, + CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, + CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, + CASE WHEN s_tot THEN COALESCE(f.tot_aq1,0)+COALESCE(f.tot_aq2,0)+COALESCE(f.tot_aq3,0)+COALESCE(f.tot_aq4,0) END, + CASE WHEN s_tot THEN COALESCE(f.tot_pa1,0)+COALESCE(f.tot_pa2,0)+COALESCE(f.tot_pa3,0)+COALESCE(f.tot_pa4,0) END, + f.tree_path || ARRAY[f.lid] AS _sort, + f.lid::BIGINT AS _k + FROM final_input f + + UNION ALL + + SELECT + CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR, + t.depth, NULL::INT, + v_year, + CASE + WHEN t.depth < 3 THEN t.item_id + WHEN t.depth = 3 THEN t.parent_item_id + WHEN t.depth = 4 THEN t.grandparent_item_id + END, + CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL::VARCHAR END, + t.num_group_id, t.name, NULL::VARCHAR, + CASE WHEN s_plan THEN ta.sp1 END, + CASE WHEN s_plan THEN ta.sp2 END, + CASE WHEN s_plan THEN ta.sp3 END, + CASE WHEN s_plan THEN ta.sp4 END, + CASE WHEN s_plan THEN (COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0)) END, + NULL::VARCHAR, + CASE WHEN s_cs THEN ta.scst END, + NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_cs THEN ta.sfy1 END, + CASE WHEN s_cs THEN ta.sfy2 END, + CASE WHEN s_cs THEN ta.sossp END, + NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_seq THEN ta.ss1 END, + CASE WHEN s_seq THEN ta.ss2 END, + CASE WHEN s_seq THEN ta.ss3 END, + CASE WHEN s_seq THEN ta.ss4 END, + CASE WHEN s_seq THEN (COALESCE(ta.ss1,0)+COALESCE(ta.ss2,0)+COALESCE(ta.ss3,0)+COALESCE(ta.ss4,0)) END, + NULL::VARCHAR, + CASE WHEN s_res THEN ta.sr1 END, + CASE WHEN s_res THEN ta.sr2 END, + CASE WHEN s_res THEN ta.sr3 END, + CASE WHEN s_res THEN ta.sr4 END, + CASE WHEN s_res THEN (COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0)) END, + NULL::VARCHAR, + CASE WHEN s_appr THEN (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) END, + CASE WHEN s_appr THEN (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) END, + CASE WHEN s_appr THEN (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) END, + CASE WHEN s_appr THEN (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) END, + CASE WHEN s_appr THEN (COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) + +COALESCE(ta.ss1,0)+COALESCE(ta.ss2,0)+COALESCE(ta.ss3,0)+COALESCE(ta.ss4,0) + +COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0)) END, + CASE WHEN s_ca THEN ta.sca END, + NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_ckk THEN ta.sckc END, + CASE WHEN s_ckk THEN ta.sck1 END, + CASE WHEN s_ckk THEN ta.sck2 END, + CASE WHEN s_ckk THEN ta.sck3 END, + CASE WHEN s_ckk THEN ta.sck4 END, + NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, + NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_cd THEN ta.scdc END, + CASE WHEN s_cd THEN ta.scd1 END, + CASE WHEN s_cd THEN ta.scd2 END, + CASE WHEN s_cd THEN ta.scd3 END, + CASE WHEN s_cd THEN ta.scd4 END, + NULL::VARCHAR, NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_q1 THEN tb1.ac END, + CASE WHEN s_q1 THEN tb1.as2 END, + CASE WHEN s_q1 THEN tb1.ar END, + CASE WHEN s_q1 THEN tb1.arv END, + NULL::VARCHAR, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) + + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)), 0) + END, + NULL::DATE, + CASE WHEN s_q1 THEN tb1.pa END, + CASE WHEN s_q1 THEN tb1.pho END, + CASE WHEN s_q1 THEN tb1.prf END, + NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_q1 THEN ta.bk1 END, + CASE WHEN s_q1 THEN tb1.m1 END, + CASE WHEN s_q1 THEN tb1.m2 END, + CASE WHEN s_q1 THEN tb1.m3 END, + CASE WHEN s_q1 THEN (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)) END, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) + + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) + - COALESCE(ta.bk1,0) + END, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) + + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) + - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0) + END, + CASE WHEN s_q1 THEN tb1.tq2 END, + CASE WHEN s_q1 THEN tb1.tq3 END, + CASE WHEN s_q1 THEN tb1.tq4 END, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) + + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) + - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0) + - COALESCE((COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)),0) + END, + CASE WHEN s_q1 THEN + (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) + + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) + - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0) + END, + CASE WHEN s_q2 THEN tb2.reco END, + CASE WHEN s_q2 THEN tb2.ritm END, + CASE WHEN s_q2 THEN tb2.rinc END, + CASE WHEN s_q2 THEN tb2.rseq END, + NULL::VARCHAR, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) + + COALESCE(tb1.tq2, 0) + + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)), 0) + END, + CASE WHEN s_q2 THEN tb2.ac END, + CASE WHEN s_q2 THEN tb2.as2 END, + CASE WHEN s_q2 THEN tb2.ar END, + CASE WHEN s_q2 THEN tb2.arv END, + NULL::VARCHAR, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) + + COALESCE(tb1.tq2, 0) + + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)), 0) + END, + NULL::DATE, + CASE WHEN s_q2 THEN tb2.pa END, + CASE WHEN s_q2 THEN tb2.pho END, + CASE WHEN s_q2 THEN tb2.prf END, + NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_q2 THEN ta.bk2 END, + CASE WHEN s_q2 THEN tb2.m1 END, + CASE WHEN s_q2 THEN tb2.m2 END, + CASE WHEN s_q2 THEN tb2.m3 END, + CASE WHEN s_q2 THEN (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)) END, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) + + COALESCE(tb1.tq2,0) + + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) + - COALESCE(ta.bk2,0) + END, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) + + COALESCE(tb1.tq2,0) + + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) + - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0) + END, + CASE WHEN s_q2 THEN tb2.tq3 END, + CASE WHEN s_q2 THEN tb2.tq4 END, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) + + COALESCE(tb1.tq2,0) + + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) + - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0) + - COALESCE((COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)),0) + END, + CASE WHEN s_q2 THEN + (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) + + COALESCE(tb1.tq2,0) + + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) + - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0) + END, + CASE WHEN s_q3 THEN tb3.reco END, + CASE WHEN s_q3 THEN tb3.ritm END, + CASE WHEN s_q3 THEN tb3.rinc END, + CASE WHEN s_q3 THEN tb3.rseq END, + NULL::VARCHAR, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) + + COALESCE(tb1.tq3, 0) + + COALESCE(tb2.tq3, 0) + + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)), 0) + END, + CASE WHEN s_q3 THEN tb3.ac END, + CASE WHEN s_q3 THEN tb3.as2 END, + CASE WHEN s_q3 THEN tb3.ar END, + CASE WHEN s_q3 THEN tb3.arv END, + NULL::VARCHAR, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) + + COALESCE(tb1.tq3, 0) + + COALESCE(tb2.tq3, 0) + + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)), 0) + END, + NULL::DATE, + CASE WHEN s_q3 THEN tb3.pa END, + CASE WHEN s_q3 THEN tb3.pho END, + CASE WHEN s_q3 THEN tb3.prf END, + NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_q3 THEN ta.bk3 END, + CASE WHEN s_q3 THEN tb3.m1 END, + CASE WHEN s_q3 THEN tb3.m2 END, + CASE WHEN s_q3 THEN tb3.m3 END, + CASE WHEN s_q3 THEN (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)) END, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) + + COALESCE(tb1.tq3,0) + + COALESCE(tb2.tq3,0) + + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) + - COALESCE(ta.bk3,0) + END, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) + + COALESCE(tb1.tq3,0) + + COALESCE(tb2.tq3,0) + + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) + - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0) + END, + CASE WHEN s_q3 THEN tb3.tq4 END, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) + + COALESCE(tb1.tq3,0) + + COALESCE(tb2.tq3,0) + + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) + - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0) + - COALESCE(COALESCE(tb3.tq4,0),0) + END, + CASE WHEN s_q3 THEN + (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) + + COALESCE(tb1.tq3,0) + + COALESCE(tb2.tq3,0) + + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) + - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0) + END, + CASE WHEN s_q4 THEN tb4.reco END, + CASE WHEN s_q4 THEN tb4.ritm END, + CASE WHEN s_q4 THEN tb4.rinc END, + CASE WHEN s_q4 THEN tb4.rseq END, + NULL::VARCHAR, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) + + COALESCE(tb1.tq4, 0) + + COALESCE(tb2.tq4, 0) + + COALESCE(tb3.tq4, 0) + + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)), 0) + END, + CASE WHEN s_q4 THEN tb4.ac END, + CASE WHEN s_q4 THEN tb4.as2 END, + CASE WHEN s_q4 THEN tb4.ar END, + CASE WHEN s_q4 THEN tb4.arv END, + NULL::VARCHAR, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) + + COALESCE(tb1.tq4, 0) + + COALESCE(tb2.tq4, 0) + + COALESCE(tb3.tq4, 0) + + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)), 0) + END, + NULL::DATE, + CASE WHEN s_q4 THEN tb4.pa END, + CASE WHEN s_q4 THEN tb4.pho END, + CASE WHEN s_q4 THEN tb4.prf END, + NULL::VARCHAR, NULL::VARCHAR, + CASE WHEN s_q4 THEN ta.bk4 END, + CASE WHEN s_q4 THEN tb4.m1 END, + CASE WHEN s_q4 THEN tb4.m2 END, + CASE WHEN s_q4 THEN tb4.m3 END, + CASE WHEN s_q4 THEN (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)) END, + CASE WHEN s_q4 THEN tb4.spod END, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) + + COALESCE(tb1.tq4,0) + + COALESCE(tb2.tq4,0) + + COALESCE(tb3.tq4,0) + + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) + - COALESCE(ta.bk4,0) + END, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) + + COALESCE(tb1.tq4,0) + + COALESCE(tb2.tq4,0) + + COALESCE(tb3.tq4,0) + + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) + - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0) + END, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) + + COALESCE(tb1.tq4,0) + + COALESCE(tb2.tq4,0) + + COALESCE(tb3.tq4,0) + + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) + - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0) + END, + CASE WHEN s_q4 THEN + (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) + + COALESCE(tb1.tq4,0) + + COALESCE(tb2.tq4,0) + + COALESCE(tb3.tq4,0) + + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) + - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0) + END, + CASE WHEN s_tot THEN (COALESCE(tt.fq1,0)+COALESCE(tt.fq2,0)+COALESCE(tt.fq3,0)+COALESCE(tt.fq4,0)) END, + CASE WHEN s_tot THEN tt.pay END, + t.path AS _sort, + -t.id::BIGINT + + FROM tw_f t + LEFT JOIN tw_agg ta ON ta.id = t.id + LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id + LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id + LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id + LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id + LEFT JOIN tw_atot tt ON tt.id = t.id + ) sub(row_type, depth, line_id, col_b_year, col_c_section, col_d_item_id, col_e_num_group, col_f_name, col_g_internal_order, col_h_plan_q1, col_i_plan_q2, col_j_plan_q3, col_k_plan_q4, col_l_plan_year, col_m_plan_comment, col_n_cs_total, col_o_cs_counterparty, col_p_cs_deadline, col_q_cs_comment, col_r_cs_future_y1, col_s_cs_future_y2, col_t_cs_other_ssp, col_v_al_order, col_w_al_property, col_y_seq_q1, col_z_seq_q2, col_aa_seq_q3, col_ab_seq_q4, col_ac_seq_year, col_ad_seq_justification, col_af_res_q1, col_ag_res_q2, col_ah_res_q3, col_ai_res_q4, col_aj_res_year, col_ak_res_justification, col_am_approved_q1, col_an_approved_q2, col_ao_approved_q3, col_ap_approved_q4, col_aq_approved_year, col_as_ca_approved, col_at_ca_protocol, col_au_ca_note, col_aw_ckk_ceiling, col_ax_ckk_exp_q1, col_ay_ckk_exp_q2, col_az_ckk_exp_q3, col_ba_ckk_exp_q4, col_bb_ckk_rf_sched, col_bc_ckk_deadline, col_bd_ckk_proc_plan, col_be_ckk_proc_meth, col_bf_ckk_comment, col_bh_cd_counterparty, col_bi_cd_reference, col_bj_cd_addenda, col_bk_cd_subject, col_bl_cd_currency, col_bm_cd_ceiling, col_bn_cd_exp_q1, col_bo_cd_exp_q2, col_bp_cd_exp_q3, col_bq_cd_exp_q4, col_br_cd_rf_sched, col_bs_cd_vat, col_bt_cd_rate, col_bu_cd_amount_fx, col_bv_cd_deadline, col_bw_cd_scheme, col_bx_cd_act, col_by_cd_comment, col_ca_q1_adj_current, col_cb_q1_adj_ssp, col_cc_q1_adj_rf, col_cd_q1_adj_reserve, col_ce_q1_adj_comment, col_cf_q1_corrected_plan, col_ch_q1_pay_date, col_ci_q1_pay_amount, col_cj_q1_pay_ho, col_ck_q1_pay_rf, col_cl_q1_pay_comment, col_cm_q1_pay_act, col_co_q1_booking, col_cp_q1_actual_m1, col_cq_q1_actual_m2, col_cr_q1_actual_m3, col_cs_q1_actual_quarter, col_ct_q1_rem_booking, col_cu_q1_rem_actual, col_cw_q1_trans_q2, col_cx_q1_trans_q3, col_cy_q1_trans_q4, col_cz_q1_economy, col_da_q1_total, col_dc_q2_rev_eco, col_dd_q2_rev_item, col_de_q2_rev_inc, col_df_q2_rev_seq, col_dg_q2_rev_comment, col_dh_q2_new_plan, col_dj_q2_adj_current, col_dk_q2_adj_ssp, col_dl_q2_adj_rf, col_dm_q2_adj_reserve, col_dn_q2_adj_comment, col_do_q2_corrected_plan, col_dq_q2_pay_date, col_dr_q2_pay_amount, col_ds_q2_pay_ho, col_dt_q2_pay_rf, col_du_q2_pay_comment, col_dv_q2_pay_act, col_dx_q2_booking, col_dy_q2_actual_m1, col_dz_q2_actual_m2, col_ea_q2_actual_m3, col_eb_q2_actual_quarter, col_ec_q2_rem_booking, col_ed_q2_rem_actual, col_ef_q2_trans_q3, col_eg_q2_trans_q4, col_eh_q2_economy, col_ei_q2_total, col_ek_q3_rev_eco, col_el_q3_rev_item, col_em_q3_rev_inc, col_en_q3_rev_seq, col_eo_q3_rev_comment, col_ep_q3_new_plan, col_er_q3_adj_current, col_es_q3_adj_ssp, col_et_q3_adj_rf, col_eu_q3_adj_reserve, col_ev_q3_adj_comment, col_ew_q3_corrected_plan, col_ey_q3_pay_date, col_ez_q3_pay_amount, col_fa_q3_pay_ho, col_fb_q3_pay_rf, col_fc_q3_pay_comment, col_fd_q3_pay_act, col_ff_q3_booking, col_fg_q3_actual_m1, col_fh_q3_actual_m2, col_fi_q3_actual_m3, col_fj_q3_actual_quarter, col_fk_q3_rem_booking, col_fl_q3_rem_actual, col_fn_q3_trans_q4, col_fo_q3_economy, col_fp_q3_total, col_fr_q4_rev_eco, col_fs_q4_rev_item, col_ft_q4_rev_inc, col_fu_q4_rev_seq, col_fv_q4_rev_comment, col_fw_q4_new_plan, col_fy_q4_adj_current, col_fz_q4_adj_ssp, col_ga_q4_adj_rf, col_gb_q4_adj_reserve, col_gc_q4_adj_comment, col_gd_q4_corrected_plan, col_gf_q4_pay_date, col_gg_q4_pay_amount, col_gh_q4_pay_ho, col_gi_q4_pay_rf, col_gj_q4_pay_comment, col_gk_q4_pay_act, col_gm_q4_booking, col_gn_q4_actual_m1, col_go_q4_actual_m2, col_gp_q4_actual_m3, col_gq_q4_actual_quarter, col_gr_q4_actual_spod, col_gs_q4_rem_booking, col_gt_q4_rem_actual, col_gv_q4_economy, col_gw_q4_total, col_gz_fact_year, col_hb_pay_year, _sort_path, _k) + JOIN sk ON sk.k = sub._k + ORDER BY sk.rnk; + +END; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.v_form2_sheet_jsonb(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) + RETURNS TABLE(row_type character varying, depth integer, line_id integer, header jsonb, plan_data jsonb, seq_dfip_data jsonb, seq_ssp_data jsonb, approved_data jsonb, contract_data jsonb, booking_data jsonb, contract_summary jsonb, allocation_data jsonb, collegial_data jsonb, ckk_data jsonb, q1_data jsonb, q2_data jsonb, q3_data jsonb, q4_data jsonb, totals_data jsonb, _sort_path integer[], _sort_rank bigint) + LANGUAGE sql + STABLE +AS $function$ + WITH flags AS ( + SELECT + (p_sections IS NULL OR 'plan' = ANY(p_sections)) AS s_plan, + (p_sections IS NULL OR 'seq_dfip' = ANY(p_sections)) AS s_seq_d, + (p_sections IS NULL OR 'seq_ssp' = ANY(p_sections)) AS s_seq_s, + (p_sections IS NULL OR 'approved' = ANY(p_sections)) AS s_appr, + (p_sections IS NULL OR 'contract' = ANY(p_sections)) AS s_cd, + (p_sections IS NULL OR 'booking' = ANY(p_sections)) AS s_book, + (p_sections IS NULL OR 'contract_summary' = ANY(p_sections)) AS s_cs, + (p_sections IS NULL OR 'allocation' = ANY(p_sections)) AS s_al, + (p_sections IS NULL OR 'collegial' = ANY(p_sections)) AS s_ca, + (p_sections IS NULL OR 'ckk' = ANY(p_sections)) AS s_ckk, + (p_sections IS NULL OR 'q1' = ANY(p_sections)) AS s_q1, + (p_sections IS NULL OR 'q2' = ANY(p_sections)) AS s_q2, + (p_sections IS NULL OR 'q3' = ANY(p_sections)) AS s_q3, + (p_sections IS NULL OR 'q4' = ANY(p_sections)) AS s_q4, + (p_sections IS NULL OR 'totals' = ANY(p_sections)) AS s_tot + ) + SELECT + s.row_type, s.depth, s.line_id, + + jsonb_build_object( + 'section_code', s.col_section_code, + 'item_id', s.col_item_id, + 'num_group', s.col_num_group_id, + 'name', s.col_name, + 'vsp_id', s.col_vsp_id, + 'vsp_address', s.col_vsp_address, + 'internal_order', s.col_internal_order, + 'expense_item_id', CASE WHEN s.row_type = 'INPUT' + THEN s._sort_path[array_upper(s._sort_path,1)-1] + ELSE s._sort_path[array_upper(s._sort_path,1)] END + ) AS header, + + CASE WHEN f.s_plan THEN jsonb_build_object( + 'q1', s.col_plan_q1, 'q2', s.col_plan_q2, + 'q3', s.col_plan_q3, 'q4', s.col_plan_q4, + 'year', s.col_plan_year, 'comment', s.col_plan_comment + ) END AS plan_data, + + CASE WHEN f.s_seq_d THEN jsonb_build_object( + 'q1', s.col_seq_dfip_q1, 'q2', s.col_seq_dfip_q2, + 'q3', s.col_seq_dfip_q3, 'q4', s.col_seq_dfip_q4, + 'year', s.col_seq_dfip_year, + 'justification', s.col_seq_dfip_just + ) END AS seq_dfip_data, + + CASE WHEN f.s_seq_s THEN jsonb_build_object( + 'q1', s.col_seq_ssp_q1, 'q2', s.col_seq_ssp_q2, + 'q3', s.col_seq_ssp_q3, 'q4', s.col_seq_ssp_q4, + 'year', s.col_seq_ssp_year, + 'justification', s.col_seq_ssp_just + ) END AS seq_ssp_data, + + CASE WHEN f.s_appr THEN jsonb_build_object( + 'q1', s.col_appr_q1, 'q2', s.col_appr_q2, + 'q3', s.col_appr_q3, 'q4', s.col_appr_q4, + 'year', s.col_appr_year + ) END AS approved_data, + + CASE WHEN f.s_cd THEN jsonb_build_object( + 'counterparty', s.col_cd_counterparty, + 'reference', s.col_cd_reference, + 'addenda', s.col_cd_addenda, + 'date', TO_CHAR(s.col_cd_date, 'DD.MM.YYYY'), + 'subject', s.col_cd_subject, + 'currency', s.col_cd_currency, + 'ceiling', s.col_cd_ceiling, + 'q1', s.col_cd_exp_q1, + 'q2', s.col_cd_exp_q2, + 'q3', s.col_cd_exp_q3, + 'q4', s.col_cd_exp_q4, + 'rf_schedule', s.col_cd_rf_sched, + 'vat_rate', s.col_cd_vat_rate, + 'exchange_rate', s.col_cd_exchange_rate, + 'amount_foreign', s.col_cd_amount_foreign, + 'deadline', s.col_cd_deadline, + 'scheme', s.col_cd_scheme, + 'act', s.col_cd_act, + 'comment', s.col_cd_comment + ) END AS contract_data, + + CASE WHEN f.s_book THEN jsonb_build_object( + 'y2026', jsonb_build_object('q1', s.col_book_q1, 'q2', s.col_book_q2, 'q3', s.col_book_q3, 'q4', s.col_book_q4), + 'y2027', jsonb_build_object('q1', s.col_book_next_q1, 'q2', s.col_book_next_q2, 'q3', s.col_book_next_q3, 'q4', s.col_book_next_q4) + ) END AS booking_data, + + CASE WHEN f.s_cs THEN jsonb_build_object( + 'total', s.col_cs_total, + 'counterparty', s.col_cs_counterparty, + 'deadline', s.col_cs_deadline, + 'comment', s.col_cs_comment, + 'future_y1', s.col_cs_future_y1, + 'future_y2', s.col_cs_future_y2, + 'other_ssp', s.col_cs_other_ssp + ) END AS contract_summary, + + CASE WHEN f.s_al THEN jsonb_build_object( + 'contract_ref', s.col_al_contract_ref, + 'purpose', s.col_al_purpose, + 'order', s.col_al_order, + 'property', s.col_al_property + ) END AS allocation_data, + + CASE WHEN f.s_ca THEN jsonb_build_object( + 'approved', s.col_ca_approved, + 'protocol', s.col_ca_protocol, + 'note', s.col_ca_note + ) END AS collegial_data, + + CASE WHEN f.s_ckk THEN jsonb_build_object( + 'ceiling', s.col_ckk_ceiling, + 'rf_schedule', s.col_ckk_rf_sched, + 'deadline', s.col_ckk_deadline, + 'proc_plan', s.col_ckk_proc_plan, + 'proc_method', s.col_ckk_proc_meth, + 'comment', s.col_ckk_comment + ) END AS ckk_data, + + CASE WHEN f.s_q1 THEN jsonb_build_object( + 'adj_current', s.col_q1_adj_current, + 'adj_ssp', s.col_q1_adj_ssp, + 'adj_rf', s.col_q1_adj_rf, + 'adj_reserve', s.col_q1_adj_reserve, + 'adj_comment', s.col_q1_adj_comment, + 'corrected_plan', s.col_q1_corrected_plan, + 'pay_date', TO_CHAR(s.col_q1_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_q1_pay_amount, + 'pay_ho', s.col_q1_pay_ho, + 'pay_rf', s.col_q1_pay_rf, + 'pay_comment', s.col_q1_pay_comment, + 'pay_act', s.col_q1_pay_act, + 'booking', s.col_q1_booking, + 'actual_m1', s.col_q1_actual_m1, + 'actual_m2', s.col_q1_actual_m2, + 'actual_m3', s.col_q1_actual_m3, + 'actual_quarter', s.col_q1_actual_quarter, + 'residual_after_booking', s.col_q1_residual_after_booking, + 'residual_after_actual', s.col_q1_residual_after_actual, + 'transfer_q2', s.col_q1_transfer_q2, + 'transfer_q2_delay_acts', s.col_q1_transfer_q2_delay_acts, + 'transfer_q2_delay_procurement', s.col_q1_transfer_q2_delay_procurement, + 'transfer_q2_economy_rf', s.col_q1_transfer_q2_economy_rf, + 'transfer_next_comment', s.col_q1_transfer_next_comment, + 'transfer_q3', s.col_q1_transfer_q3, + 'transfer_q4', s.col_q1_transfer_q4, + 'transfer_far_comment', s.col_q1_transfer_far_comment, + 'transfer_econ', s.col_q1_transfer_econ, + 'total', s.col_q1_total + ) END AS q1_data, + + CASE WHEN f.s_q2 THEN jsonb_build_object( + 'target_change', s.col_q2_target_change, + 'base_correction', s.col_q2_base_correction, + 'base_correction_comment', s.col_q2_base_correction_comment, + 'revision_inc', s.col_q2_revision_inc, + 'revision_seq', s.col_q2_revision_seq, + 'revision_comment', s.col_q2_revision_comment, + 'new_plan', s.col_q2_new_plan, + 'adj_current', s.col_q2_adj_current, + 'adj_ssp', s.col_q2_adj_ssp, + 'adj_rf', s.col_q2_adj_rf, + 'adj_reserve', s.col_q2_adj_reserve, + 'adj_comment', s.col_q2_adj_comment, + 'corrected_plan', s.col_q2_corrected_plan, + 'pay_date', TO_CHAR(s.col_q2_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_q2_pay_amount, + 'pay_ho', s.col_q2_pay_ho, + 'pay_rf', s.col_q2_pay_rf, + 'pay_comment', s.col_q2_pay_comment, + 'pay_act', s.col_q2_pay_act, + 'booking', s.col_q2_booking, + 'actual_m1', s.col_q2_actual_m1, + 'actual_m2', s.col_q2_actual_m2, + 'actual_m3', s.col_q2_actual_m3, + 'actual_quarter', s.col_q2_actual_quarter, + 'residual_after_booking', s.col_q2_residual_after_booking, + 'residual_after_actual', s.col_q2_residual_after_actual, + 'transfer_q3', s.col_q2_transfer_q3, + 'transfer_q3_delay_acts', s.col_q2_transfer_q3_delay_acts, + 'transfer_q3_delay_procurement', s.col_q2_transfer_q3_delay_procurement, + 'transfer_q3_economy_rf', s.col_q2_transfer_q3_economy_rf, + 'transfer_next_comment', s.col_q2_transfer_next_comment, + 'transfer_q4', s.col_q2_transfer_q4, + 'transfer_far_comment', s.col_q2_transfer_far_comment, + 'transfer_econ', s.col_q2_transfer_econ, + 'total', s.col_q2_total + ) END AS q2_data, + + CASE WHEN f.s_q3 THEN jsonb_build_object( + 'target_change', s.col_q3_target_change, + 'base_correction', s.col_q3_base_correction, + 'base_correction_comment', s.col_q3_base_correction_comment, + 'revision_inc', s.col_q3_revision_inc, + 'revision_seq', s.col_q3_revision_seq, + 'revision_comment', s.col_q3_revision_comment, + 'new_plan', s.col_q3_new_plan, + 'adj_current', s.col_q3_adj_current, + 'adj_ssp', s.col_q3_adj_ssp, + 'adj_rf', s.col_q3_adj_rf, + 'adj_reserve', s.col_q3_adj_reserve, + 'adj_comment', s.col_q3_adj_comment, + 'corrected_plan', s.col_q3_corrected_plan, + 'pay_date', TO_CHAR(s.col_q3_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_q3_pay_amount, + 'pay_ho', s.col_q3_pay_ho, + 'pay_rf', s.col_q3_pay_rf, + 'pay_comment', s.col_q3_pay_comment, + 'pay_act', s.col_q3_pay_act, + 'booking', s.col_q3_booking, + 'actual_m1', s.col_q3_actual_m1, + 'actual_m2', s.col_q3_actual_m2, + 'actual_m3', s.col_q3_actual_m3, + 'actual_quarter', s.col_q3_actual_quarter, + 'residual_after_booking', s.col_q3_residual_after_booking, + 'residual_after_actual', s.col_q3_residual_after_actual, + 'transfer_q4', s.col_q3_transfer_q4, + 'transfer_q4_delay_acts', s.col_q3_transfer_q4_delay_acts, + 'transfer_q4_delay_procurement', s.col_q3_transfer_q4_delay_procurement, + 'transfer_q4_economy_rf', s.col_q3_transfer_q4_economy_rf, + 'transfer_next_comment', s.col_q3_transfer_next_comment, + 'transfer_econ', s.col_q3_transfer_econ, + 'total', s.col_q3_total + ) END AS q3_data, + + CASE WHEN f.s_q4 THEN jsonb_build_object( + 'target_change', s.col_q4_target_change, + 'base_correction', s.col_q4_base_correction, + 'base_correction_comment', s.col_q4_base_correction_comment, + 'revision_inc', s.col_q4_revision_inc, + 'revision_seq', s.col_q4_revision_seq, + 'revision_comment', s.col_q4_revision_comment, + 'new_plan', s.col_q4_new_plan, + 'adj_current', s.col_q4_adj_current, + 'adj_ssp', s.col_q4_adj_ssp, + 'adj_rf', s.col_q4_adj_rf, + 'adj_reserve', s.col_q4_adj_reserve, + 'adj_comment', s.col_q4_adj_comment, + 'corrected_plan', s.col_q4_corrected_plan, + 'pay_date', TO_CHAR(s.col_q4_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_q4_pay_amount, + 'pay_ho', s.col_q4_pay_ho, + 'pay_rf', s.col_q4_pay_rf, + 'pay_comment', s.col_q4_pay_comment, + 'pay_act', s.col_q4_pay_act, + 'booking', s.col_q4_booking, + 'actual_m1', s.col_q4_actual_m1, + 'actual_m2', s.col_q4_actual_m2, + 'actual_m3', s.col_q4_actual_m3, + 'actual_spod', s.col_q4_actual_spod, + 'actual_quarter', s.col_q4_actual_quarter, + 'residual_after_booking', s.col_q4_residual_after_booking, + 'residual_after_actual', s.col_q4_residual_after_actual, + 'transfer_econ', s.col_q4_transfer_econ, + 'total', s.col_q4_total + ) END AS q4_data, + + CASE WHEN f.s_tot THEN jsonb_build_object( + 'fact_year', s.col_fact_year, + 'pay_year', s.col_pay_year, + 'economy_year', s.col_economy_year + ) END AS totals_data, + + s._sort_path, + s._sort_rank + FROM v3.v_form2_sheet_sections(p_form_id, p_sheet, p_sections, p_focus_lines) s + CROSS JOIN flags f + ORDER BY s._sort_rank; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.v_form1_sheet_jsonb(p_form_id integer, p_sheet character varying, p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) + RETURNS TABLE(row_type character varying, depth integer, line_id integer, header jsonb, plan_data jsonb, contract_summary jsonb, allocation_data jsonb, sequestration_data jsonb, reserve_data jsonb, approved_data jsonb, collegial_data jsonb, ckk_data jsonb, contract_detail jsonb, q1_data jsonb, q2_data jsonb, q3_data jsonb, q4_data jsonb, totals_data jsonb, _sort_path integer[], _sort_rank bigint) + LANGUAGE sql + STABLE + SET search_path TO 'v3', 'pg_catalog' +AS $function$ + WITH flags AS ( + SELECT + (p_sections IS NULL OR 'plan' = ANY(p_sections)) AS s_plan, + (p_sections IS NULL OR 'contract_summary' = ANY(p_sections)) AS s_cs, + (p_sections IS NULL OR 'allocation' = ANY(p_sections)) AS s_al, + (p_sections IS NULL OR 'sequestration' = ANY(p_sections)) AS s_seq, + (p_sections IS NULL OR 'reserve' = ANY(p_sections)) AS s_res, + (p_sections IS NULL OR 'approved' = ANY(p_sections)) AS s_appr, + (p_sections IS NULL OR 'collegial' = ANY(p_sections)) AS s_ca, + (p_sections IS NULL OR 'ckk' = ANY(p_sections)) AS s_ckk, + (p_sections IS NULL OR 'contract_detail' = ANY(p_sections)) AS s_cd, + (p_sections IS NULL OR 'q1' = ANY(p_sections)) AS s_q1, + (p_sections IS NULL OR 'q2' = ANY(p_sections)) AS s_q2, + (p_sections IS NULL OR 'q3' = ANY(p_sections)) AS s_q3, + (p_sections IS NULL OR 'q4' = ANY(p_sections)) AS s_q4, + (p_sections IS NULL OR 'totals' = ANY(p_sections)) AS s_tot + ) + SELECT + s.row_type, s.depth, s.line_id, + + jsonb_build_object( + 'year', s.col_B_year, + 'section', s.col_C_section, + 'item_id', s.col_D_item_id, + 'num_group', s.col_E_num_group, + 'name', s.col_F_name, + 'internal_order', s.col_G_internal_order, + 'expense_item_id', CASE WHEN s.row_type = 'INPUT' + THEN s._sort_path[array_upper(s._sort_path,1)-1] + ELSE s._sort_path[array_upper(s._sort_path,1)] END + ) AS header, + + CASE WHEN f.s_plan THEN jsonb_build_object( + 'q1', s.col_H_plan_q1, + 'q2', s.col_I_plan_q2, + 'q3', s.col_J_plan_q3, + 'q4', s.col_K_plan_q4, + 'year', s.col_L_plan_year, + 'comment', s.col_M_plan_comment + ) END AS plan_data, + + CASE WHEN f.s_cs THEN jsonb_build_object( + 'total', s.col_N_cs_total, + 'counterparty', s.col_O_cs_counterparty, + 'deadline', s.col_P_cs_deadline, + 'comment', s.col_Q_cs_comment, + 'future_y1', s.col_R_cs_future_y1, + 'future_y2', s.col_S_cs_future_y2, + 'other_ssp', s.col_T_cs_other_ssp + ) END AS contract_summary, + + CASE WHEN f.s_al THEN jsonb_build_object( + 'order', s.col_V_al_order, + 'property', s.col_W_al_property + ) END AS allocation_data, + + CASE WHEN f.s_seq THEN jsonb_build_object( + 'q1', s.col_Y_seq_q1, + 'q2', s.col_Z_seq_q2, + 'q3', s.col_AA_seq_q3, + 'q4', s.col_AB_seq_q4, + 'year', s.col_AC_seq_year, + 'justification', s.col_AD_seq_justification + ) END AS sequestration_data, + + CASE WHEN f.s_res THEN jsonb_build_object( + 'q1', s.col_AF_res_q1, + 'q2', s.col_AG_res_q2, + 'q3', s.col_AH_res_q3, + 'q4', s.col_AI_res_q4, + 'year', s.col_AJ_res_year, + 'justification', s.col_AK_res_justification + ) END AS reserve_data, + + CASE WHEN f.s_appr THEN jsonb_build_object( + 'q1', s.col_AM_approved_q1, + 'q2', s.col_AN_approved_q2, + 'q3', s.col_AO_approved_q3, + 'q4', s.col_AP_approved_q4, + 'year', s.col_AQ_approved_year + ) END AS approved_data, + + CASE WHEN f.s_ca THEN jsonb_build_object( + 'approved', s.col_AS_ca_approved, + 'protocol', s.col_AT_ca_protocol, + 'note', s.col_AU_ca_note + ) END AS collegial_data, + + CASE WHEN f.s_ckk THEN jsonb_build_object( + 'ceiling', s.col_AW_ckk_ceiling, + 'q1', s.col_AX_ckk_exp_q1, + 'q2', s.col_AY_ckk_exp_q2, + 'q3', s.col_AZ_ckk_exp_q3, + 'q4', s.col_BA_ckk_exp_q4, + 'rf_schedule', s.col_BB_ckk_rf_sched, + 'deadline', s.col_BC_ckk_deadline, + 'proc_plan', s.col_BD_ckk_proc_plan, + 'proc_method', s.col_BE_ckk_proc_meth, + 'comment', s.col_BF_ckk_comment + ) END AS ckk_data, + + CASE WHEN f.s_cd THEN jsonb_build_object( + 'counterparty', s.col_BH_cd_counterparty, + 'reference', s.col_BI_cd_reference, + 'addenda', s.col_BJ_cd_addenda, + 'subject', s.col_BK_cd_subject, + 'currency', s.col_BL_cd_currency, + 'ceiling', s.col_BM_cd_ceiling, + 'q1', s.col_BN_cd_exp_q1, + 'q2', s.col_BO_cd_exp_q2, + 'q3', s.col_BP_cd_exp_q3, + 'q4', s.col_BQ_cd_exp_q4, + 'rf_schedule', s.col_BR_cd_rf_sched, + 'vat_rate', s.col_BS_cd_vat, + 'exchange_rate', s.col_BT_cd_rate, + 'amount_foreign', s.col_BU_cd_amount_fx, + 'deadline', s.col_BV_cd_deadline, + 'payment_scheme', s.col_BW_cd_scheme, + 'act', s.col_BX_cd_act, + 'comment', s.col_BY_cd_comment + ) END AS contract_detail, + + CASE WHEN f.s_q1 THEN jsonb_build_object( + 'adj_current', s.col_CA_q1_adj_current, + 'adj_ssp', s.col_CB_q1_adj_ssp, + 'adj_rf', s.col_CC_q1_adj_rf, + 'adj_reserve', s.col_CD_q1_adj_reserve, + 'adj_comment', s.col_CE_q1_adj_comment, + 'corrected_plan', s.col_CF_q1_corrected_plan, + 'pay_date', TO_CHAR(s.col_CH_q1_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_CI_q1_pay_amount, + 'pay_ho', s.col_CJ_q1_pay_ho, + 'pay_rf', s.col_CK_q1_pay_rf, + 'pay_comment', s.col_CL_q1_pay_comment, + 'pay_act', s.col_CM_q1_pay_act, + 'booking', s.col_CO_q1_booking, + 'actual_m1', s.col_CP_q1_actual_m1, + 'actual_m2', s.col_CQ_q1_actual_m2, + 'actual_m3', s.col_CR_q1_actual_m3, + 'actual_quarter', s.col_CS_q1_actual_quarter, + 'rem_booking', s.col_CT_q1_rem_booking, + 'rem_actual', s.col_CU_q1_rem_actual, + 'transfer_q2', s.col_CW_q1_trans_q2, + 'transfer_q3', s.col_CX_q1_trans_q3, + 'transfer_q4', s.col_CY_q1_trans_q4, + 'economy', s.col_CZ_q1_economy, + 'total', s.col_DA_q1_total + ) END AS q1_data, + + CASE WHEN f.s_q2 THEN jsonb_build_object( + 'rev_eco', s.col_DC_q2_rev_eco, + 'rev_item', s.col_DD_q2_rev_item, + 'rev_inc', s.col_DE_q2_rev_inc, + 'rev_seq', s.col_DF_q2_rev_seq, + 'rev_comment', s.col_DG_q2_rev_comment, + 'new_plan', s.col_DH_q2_new_plan, + 'adj_current', s.col_DJ_q2_adj_current, + 'adj_ssp', s.col_DK_q2_adj_ssp, + 'adj_rf', s.col_DL_q2_adj_rf, + 'adj_reserve', s.col_DM_q2_adj_reserve, + 'adj_comment', s.col_DN_q2_adj_comment, + 'corrected_plan', s.col_DO_q2_corrected_plan, + 'pay_date', TO_CHAR(s.col_DQ_q2_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_DR_q2_pay_amount, + 'pay_ho', s.col_DS_q2_pay_ho, + 'pay_rf', s.col_DT_q2_pay_rf, + 'pay_comment', s.col_DU_q2_pay_comment, + 'pay_act', s.col_DV_q2_pay_act, + 'booking', s.col_DX_q2_booking, + 'actual_m1', s.col_DY_q2_actual_m1, + 'actual_m2', s.col_DZ_q2_actual_m2, + 'actual_m3', s.col_EA_q2_actual_m3, + 'actual_quarter', s.col_EB_q2_actual_quarter, + 'rem_booking', s.col_EC_q2_rem_booking, + 'rem_actual', s.col_ED_q2_rem_actual, + 'transfer_q3', s.col_EF_q2_trans_q3, + 'transfer_q4', s.col_EG_q2_trans_q4, + 'economy', s.col_EH_q2_economy, + 'total', s.col_EI_q2_total + ) END AS q2_data, + + CASE WHEN f.s_q3 THEN jsonb_build_object( + 'rev_eco', s.col_EK_q3_rev_eco, + 'rev_item', s.col_EL_q3_rev_item, + 'rev_inc', s.col_EM_q3_rev_inc, + 'rev_seq', s.col_EN_q3_rev_seq, + 'rev_comment', s.col_EO_q3_rev_comment, + 'new_plan', s.col_EP_q3_new_plan, + 'adj_current', s.col_ER_q3_adj_current, + 'adj_ssp', s.col_ES_q3_adj_ssp, + 'adj_rf', s.col_ET_q3_adj_rf, + 'adj_reserve', s.col_EU_q3_adj_reserve, + 'adj_comment', s.col_EV_q3_adj_comment, + 'corrected_plan', s.col_EW_q3_corrected_plan, + 'pay_date', TO_CHAR(s.col_EY_q3_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_EZ_q3_pay_amount, + 'pay_ho', s.col_FA_q3_pay_ho, + 'pay_rf', s.col_FB_q3_pay_rf, + 'pay_comment', s.col_FC_q3_pay_comment, + 'pay_act', s.col_FD_q3_pay_act, + 'booking', s.col_FF_q3_booking, + 'actual_m1', s.col_FG_q3_actual_m1, + 'actual_m2', s.col_FH_q3_actual_m2, + 'actual_m3', s.col_FI_q3_actual_m3, + 'actual_quarter', s.col_FJ_q3_actual_quarter, + 'rem_booking', s.col_FK_q3_rem_booking, + 'rem_actual', s.col_FL_q3_rem_actual, + 'transfer_q4', s.col_FN_q3_trans_q4, + 'economy', s.col_FO_q3_economy, + 'total', s.col_FP_q3_total + ) END AS q3_data, + + CASE WHEN f.s_q4 THEN jsonb_build_object( + 'rev_eco', s.col_FR_q4_rev_eco, + 'rev_item', s.col_FS_q4_rev_item, + 'rev_inc', s.col_FT_q4_rev_inc, + 'rev_seq', s.col_FU_q4_rev_seq, + 'rev_comment', s.col_FV_q4_rev_comment, + 'new_plan', s.col_FW_q4_new_plan, + 'adj_current', s.col_FY_q4_adj_current, + 'adj_ssp', s.col_FZ_q4_adj_ssp, + 'adj_rf', s.col_GA_q4_adj_rf, + 'adj_reserve', s.col_GB_q4_adj_reserve, + 'adj_comment', s.col_GC_q4_adj_comment, + 'corrected_plan', s.col_GD_q4_corrected_plan, + 'pay_date', TO_CHAR(s.col_GF_q4_pay_date, 'DD.MM.YYYY'), + 'pay_amount', s.col_GG_q4_pay_amount, + 'pay_ho', s.col_GH_q4_pay_ho, + 'pay_rf', s.col_GI_q4_pay_rf, + 'pay_comment', s.col_GJ_q4_pay_comment, + 'pay_act', s.col_GK_q4_pay_act, + 'booking', s.col_GM_q4_booking, + 'actual_m1', s.col_GN_q4_actual_m1, + 'actual_m2', s.col_GO_q4_actual_m2, + 'actual_m3', s.col_GP_q4_actual_m3, + 'actual_quarter', s.col_GQ_q4_actual_quarter, + 'actual_spod', s.col_GR_q4_actual_spod, + 'rem_booking', s.col_GS_q4_rem_booking, + 'rem_actual', s.col_GT_q4_rem_actual, + 'economy', s.col_GV_q4_economy, + 'total', s.col_GW_q4_total + ) END AS q4_data, + + CASE WHEN f.s_tot THEN jsonb_build_object( + 'fact_year', s.col_GZ_fact_year, + 'pay_year', s.col_HB_pay_year + ) END AS totals_data, + + s._sort_path, + s._sort_rank + FROM v_form1_sheet_sections(p_form_id, p_sheet, p_direction, p_sections, p_focus_lines) s + CROSS JOIN flags f + ORDER BY s._sort_rank; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.v_form2_view(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql + STABLE +AS $function$ +BEGIN + + + IF p_sheet IN ('AHR','CAP','OPER') THEN + RETURN QUERY + SELECT + j.row_type, + j.depth, + j._sort_rank AS sort_order, + jsonb_build_object( + 'line_id', j.line_id, + 'header', j.header, + 'plan', j.plan_data, + 'seq_dfip', j.seq_dfip_data, + 'seq_ssp', j.seq_ssp_data, + 'approved', j.approved_data, + 'contract', j.contract_data, + 'booking', j.booking_data, + 'q1', j.q1_data, + 'q2', j.q2_data, + 'q3', j.q3_data, + 'q4', j.q4_data, + 'totals', j.totals_data + ) AS data + FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections, p_focus_lines) j + ORDER BY j._sort_rank; + RETURN; + END IF; + + + + + + + + + + + + + IF p_sheet = 'AHR_LIMIT' THEN + RETURN QUERY + WITH RECURSIVE tree AS ( + SELECT id AS root_id, id AS desc_id FROM v3.limit_template + UNION + SELECT t.root_id, child.id + FROM tree t + JOIN v3.limit_template child ON child.parent_id = t.desc_id + ), + leaf_amt AS ( + + SELECT lt.id, + fl.qty_q1, fl.qty_q2, fl.qty_q3, fl.qty_q4, + v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q1)AS amount_q1, + v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q2)AS amount_q2, + v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q3)AS amount_q3, + v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q4)AS amount_q4 + FROM v3.limit_template lt + LEFT JOIN v3.form_limit fl + ON fl.template_id = lt.id AND fl.budget_form_id = p_form_id + WHERE lt.row_type = 'LEAF' + ), + agg AS ( + SELECT t.root_id, + SUM(la.qty_q1) AS qty_q1, SUM(la.amount_q1) AS amount_q1, + SUM(la.qty_q2) AS qty_q2, SUM(la.amount_q2) AS amount_q2, + SUM(la.qty_q3) AS qty_q3, SUM(la.amount_q3) AS amount_q3, + SUM(la.qty_q4) AS qty_q4, SUM(la.amount_q4) AS amount_q4 + FROM tree t + JOIN leaf_amt la ON la.id = t.desc_id + GROUP BY t.root_id + ) + SELECT + + + CASE lt.row_type WHEN 'SECTION' THEN 'ROOT' + WHEN 'GROUP' THEN 'GROUP' + WHEN 'LEAF' THEN 'INPUT' END::VARCHAR, + CASE lt.row_type WHEN 'SECTION' THEN 0 WHEN 'GROUP' THEN 1 ELSE 2 END, + lt.sort_order::BIGINT, + jsonb_build_object( + 'id', lt.id, + 'section_no', lt.section_no, + 'expense_item_code',lt.expense_item_code, + 'name', lt.name, + 'unit', lt.unit, + 'limit_with_vat', lt.limit_with_vat, + 'limit_without_vat',lt.limit_without_vat, + 'qty_q1', a.qty_q1, 'amount_q1', a.amount_q1, + 'qty_q2', a.qty_q2, 'amount_q2', a.amount_q2, + 'qty_q3', a.qty_q3, 'amount_q3', a.amount_q3, + 'qty_q4', a.qty_q4, 'amount_q4', a.amount_q4, + 'comment', fl.comment + ) + FROM v3.limit_template lt + LEFT JOIN agg a ON a.root_id = lt.id + LEFT JOIN v3.form_limit fl + ON fl.template_id = lt.id AND fl.budget_form_id = p_form_id + WHERE p_focus_lines IS NULL + OR lt.id = ANY(v3._limit_template_path_set(p_focus_lines)) + ORDER BY lt.sort_order; + RETURN; + END IF; + + + IF p_sheet = 'AHR_RENT' THEN + RETURN QUERY + SELECT + 'INPUT'::VARCHAR, + 0, + sk._rn AS sort_order, + jsonb_build_object( + 'id', rd.id, + 'line_id', rd.line_id, + 'vsp_id', rd.vsp_id, + 'address', v.address, + 'object_type', v.format, + 'rented_area', v.total_area, + 'contract_number', rd.contract_number, + 'contract_end_date',rd.contract_end_date, + 'plan', jsonb_build_object('q1', rd.plan_q1, 'q2', rd.plan_q2, 'q3', rd.plan_q3, 'q4', rd.plan_q4, + 'year', COALESCE(rd.plan_q1,0)+COALESCE(rd.plan_q2,0)+COALESCE(rd.plan_q3,0)+COALESCE(rd.plan_q4,0)), + 'fact_q1', jsonb_build_object('jan', rd.actual_jan, 'feb', rd.actual_feb, 'mar', rd.actual_mar, + 'total', COALESCE(rd.actual_jan,0)+COALESCE(rd.actual_feb,0)+COALESCE(rd.actual_mar,0)), + 'fact_q2', jsonb_build_object('apr', rd.actual_apr, 'may', rd.actual_may, 'jun', rd.actual_jun, + 'total', COALESCE(rd.actual_apr,0)+COALESCE(rd.actual_may,0)+COALESCE(rd.actual_jun,0)), + 'fact_q3', jsonb_build_object('jul', rd.actual_jul, 'aug', rd.actual_aug, 'sep', rd.actual_sep, + 'total', COALESCE(rd.actual_jul,0)+COALESCE(rd.actual_aug,0)+COALESCE(rd.actual_sep,0)), + 'fact_q4', jsonb_build_object('oct', rd.actual_oct, 'nov', rd.actual_nov, 'dec', rd.actual_dec, + 'total', COALESCE(rd.actual_oct,0)+COALESCE(rd.actual_nov,0)+COALESCE(rd.actual_dec,0)), + 'comment', rd.comment + ) + FROM ( + SELECT rds.id, ROW_NUMBER() OVER (ORDER BY rds.id) AS _rn + FROM v3.rent_detail rds + JOIN v3.budget_line bl ON bl.id = rds.line_id + JOIN v3.vsp vs ON vs.id = rds.vsp_id + WHERE bl.budget_form_id = p_form_id + ) sk + JOIN v3.rent_detail rd ON rd.id = sk.id + JOIN v3.vsp v ON v.id = rd.vsp_id + WHERE p_focus_lines IS NULL OR rd.id = ANY(p_focus_lines) + ORDER BY sk._rn; + RETURN; + END IF; + + + IF p_sheet = 'AHR_UTILITY' THEN + RETURN QUERY + SELECT + 'INPUT'::VARCHAR, + 0, + sk._rn AS sort_order, + jsonb_build_object( + 'id', ud.id, + 'line_id', ud.line_id, + 'vsp_id', ud.vsp_id, + 'address', v.address, + 'object_type', v.format, + 'object_area', v.total_area, + 'contract_number', ud.contract_number, + 'contract_end_date',ud.contract_end_date, + 'plan', jsonb_build_object('q1', ud.plan_q1, 'q2', ud.plan_q2, 'q3', ud.plan_q3, 'q4', ud.plan_q4, + 'year', COALESCE(ud.plan_q1,0)+COALESCE(ud.plan_q2,0)+COALESCE(ud.plan_q3,0)+COALESCE(ud.plan_q4,0)), + 'fact_q1', jsonb_build_object('jan', ud.actual_jan, 'feb', ud.actual_feb, 'mar', ud.actual_mar, + 'total', COALESCE(ud.actual_jan,0)+COALESCE(ud.actual_feb,0)+COALESCE(ud.actual_mar,0)), + 'fact_q2', jsonb_build_object('apr', ud.actual_apr, 'may', ud.actual_may, 'jun', ud.actual_jun, + 'total', COALESCE(ud.actual_apr,0)+COALESCE(ud.actual_may,0)+COALESCE(ud.actual_jun,0)), + 'fact_q3', jsonb_build_object('jul', ud.actual_jul, 'aug', ud.actual_aug, 'sep', ud.actual_sep, + 'total', COALESCE(ud.actual_jul,0)+COALESCE(ud.actual_aug,0)+COALESCE(ud.actual_sep,0)), + 'fact_q4', jsonb_build_object('oct', ud.actual_oct, 'nov', ud.actual_nov, 'dec', ud.actual_dec, + 'total', COALESCE(ud.actual_oct,0)+COALESCE(ud.actual_nov,0)+COALESCE(ud.actual_dec,0)), + 'comment', ud.comment + ) + FROM ( + SELECT uds.id, ROW_NUMBER() OVER (ORDER BY uds.id) AS _rn + FROM v3.utility_detail uds + JOIN v3.budget_line bl ON bl.id = uds.line_id + JOIN v3.vsp vs ON vs.id = uds.vsp_id + WHERE bl.budget_form_id = p_form_id + ) sk + JOIN v3.utility_detail ud ON ud.id = sk.id + JOIN v3.vsp v ON v.id = ud.vsp_id + WHERE p_focus_lines IS NULL OR ud.id = ANY(p_focus_lines) + ORDER BY sk._rn; + RETURN; + END IF; + + + IF p_sheet = 'AHR_SECURITY' THEN + RETURN QUERY + SELECT + 'INPUT'::VARCHAR, + 0, + sk._rn AS sort_order, + jsonb_build_object( + 'id', sd.id, + 'line_id', sd.line_id, + 'vsp_id', sd.vsp_id, + 'address', v.address, + 'object_type', v.format, + 'object_area', v.total_area, + 'contract_number', sd.contract_number, + 'contract_end_date',sd.contract_end_date, + 'plan', jsonb_build_object('q1', sd.plan_q1, 'q2', sd.plan_q2, 'q3', sd.plan_q3, 'q4', sd.plan_q4, + 'year', COALESCE(sd.plan_q1,0)+COALESCE(sd.plan_q2,0)+COALESCE(sd.plan_q3,0)+COALESCE(sd.plan_q4,0)), + 'fact_q1', jsonb_build_object('jan', sd.actual_jan, 'feb', sd.actual_feb, 'mar', sd.actual_mar, + 'total', COALESCE(sd.actual_jan,0)+COALESCE(sd.actual_feb,0)+COALESCE(sd.actual_mar,0)), + 'fact_q2', jsonb_build_object('apr', sd.actual_apr, 'may', sd.actual_may, 'jun', sd.actual_jun, + 'total', COALESCE(sd.actual_apr,0)+COALESCE(sd.actual_may,0)+COALESCE(sd.actual_jun,0)), + 'fact_q3', jsonb_build_object('jul', sd.actual_jul, 'aug', sd.actual_aug, 'sep', sd.actual_sep, + 'total', COALESCE(sd.actual_jul,0)+COALESCE(sd.actual_aug,0)+COALESCE(sd.actual_sep,0)), + 'fact_q4', jsonb_build_object('oct', sd.actual_oct, 'nov', sd.actual_nov, 'dec', sd.actual_dec, + 'total', COALESCE(sd.actual_oct,0)+COALESCE(sd.actual_nov,0)+COALESCE(sd.actual_dec,0)), + 'comment', sd.comment + ) + FROM ( + SELECT sds.id, ROW_NUMBER() OVER (ORDER BY sds.id) AS _rn + FROM v3.security_detail sds + JOIN v3.budget_line bl ON bl.id = sds.line_id + JOIN v3.vsp vs ON vs.id = sds.vsp_id + WHERE bl.budget_form_id = p_form_id + ) sk + JOIN v3.security_detail sd ON sd.id = sk.id + JOIN v3.vsp v ON v.id = sd.vsp_id + WHERE p_focus_lines IS NULL OR sd.id = ANY(p_focus_lines) + ORDER BY sk._rn; + RETURN; + END IF; + + + + + + + + + + IF p_sheet = 'OTCH9F' THEN + RETURN QUERY + WITH base AS ( + SELECT far.id, far.budget_form_id, far.expense_item_id, + far.equipment_name, far.month, + far.acquired_qty_604, far.acquired_amt_604, + far.disposed_qty_604, far.disposed_amt_604, + far.acquired_qty_60415, far.acquired_amt_60415, + far.transferred_qty_60415, far.transferred_amt_60415, + far.go_balance_only_amt, + + FIRST_VALUE(COALESCE(far.opening_qty_604,0)) + OVER w AS base_qty_604, + FIRST_VALUE(COALESCE(far.opening_amt_604,0)) + OVER w AS base_amt_604, + FIRST_VALUE(COALESCE(far.opening_qty_60415,0)) + OVER w AS base_qty_60415, + FIRST_VALUE(COALESCE(far.opening_amt_60415,0)) + OVER w AS base_amt_60415, + + COALESCE(SUM(COALESCE(far.acquired_qty_604,0) - COALESCE(far.disposed_qty_604,0)) + OVER w_prev, 0) AS cum_dq_604, + COALESCE(SUM(COALESCE(far.acquired_amt_604,0) - COALESCE(far.disposed_amt_604,0)) + OVER w_prev, 0) AS cum_da_604, + COALESCE(SUM(COALESCE(far.acquired_qty_60415,0) - COALESCE(far.transferred_qty_60415,0)) + OVER w_prev, 0) AS cum_dq_60415, + COALESCE(SUM(COALESCE(far.acquired_amt_60415,0) - COALESCE(far.transferred_amt_60415,0)) + OVER w_prev, 0) AS cum_da_60415 + FROM v3.fixed_asset_report far + WHERE far.budget_form_id = p_form_id + AND (p_focus_lines IS NULL OR EXISTS ( + SELECT 1 FROM v3.fixed_asset_report ff + WHERE ff.id = ANY(p_focus_lines) + AND ff.expense_item_id IS NOT DISTINCT FROM far.expense_item_id + AND ff.equipment_name IS NOT DISTINCT FROM far.equipment_name)) + WINDOW w AS (PARTITION BY far.budget_form_id, far.expense_item_id, far.equipment_name + ORDER BY far.month), + w_prev AS (PARTITION BY far.budget_form_id, far.expense_item_id, far.equipment_name + ORDER BY far.month + ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) + ), + eff AS ( + SELECT b.*, + (b.base_qty_604 + b.cum_dq_604) AS opening_qty_604_eff, + (b.base_amt_604 + b.cum_da_604) AS opening_amt_604_eff, + (b.base_qty_60415 + b.cum_dq_60415) AS opening_qty_60415_eff, + (b.base_amt_60415 + b.cum_da_60415) AS opening_amt_60415_eff + FROM base b + ) + SELECT + 'INPUT'::VARCHAR, + 0, + sk._rn AS sort_order, + jsonb_build_object( + 'id', eff.id, + 'expense_item_id', ei.id, + 'item_id', ei.item_id, + 'section_code', ei.section_code, + 'equipment_name', eff.equipment_name, + 'month', eff.month, + 'b_604', jsonb_build_object( + 'opening_qty', eff.opening_qty_604_eff, + 'opening_amt', eff.opening_amt_604_eff, + 'acquired_qty', eff.acquired_qty_604, + 'acquired_amt', eff.acquired_amt_604, + 'disposed_qty', eff.disposed_qty_604, + 'disposed_amt', eff.disposed_amt_604 + ), + 'b_60415', jsonb_build_object( + 'opening_qty', eff.opening_qty_60415_eff, + 'opening_amt', eff.opening_amt_60415_eff, + 'acquired_qty', eff.acquired_qty_60415, + 'acquired_amt', eff.acquired_amt_60415, + 'transferred_qty',eff.transferred_qty_60415, + 'transferred_amt',eff.transferred_amt_60415 + ), + 'totals', jsonb_build_object( + + 'acquired_total', COALESCE(eff.acquired_amt_604,0)+COALESCE(eff.acquired_amt_60415,0) + +COALESCE(eff.go_balance_only_amt,0)-COALESCE(eff.transferred_amt_60415,0), + 'go_balance_only',eff.go_balance_only_amt, + + 'disposed_total', COALESCE(eff.disposed_amt_604,0), + + 'balance_qty', (eff.opening_qty_604_eff + COALESCE(eff.acquired_qty_604,0) - COALESCE(eff.disposed_qty_604,0)) + + (eff.opening_qty_60415_eff + COALESCE(eff.acquired_qty_60415,0) - COALESCE(eff.transferred_qty_60415,0)), + 'balance_amt', (eff.opening_amt_604_eff + COALESCE(eff.acquired_amt_604,0) - COALESCE(eff.disposed_amt_604,0)) + + (eff.opening_amt_60415_eff + COALESCE(eff.acquired_amt_60415,0) - COALESCE(eff.transferred_amt_60415,0)) + ) + ) + FROM eff + JOIN v3.expense_item ei ON ei.id = eff.expense_item_id + JOIN ( + SELECT fs.id, + ROW_NUMBER() OVER (ORDER BY fs.expense_item_id, fs.month, fs.id) AS _rn + FROM v3.fixed_asset_report fs + JOIN v3.expense_item eis ON eis.id = fs.expense_item_id + WHERE fs.budget_form_id = p_form_id + ) sk ON sk.id = eff.id + ORDER BY sk._rn; + RETURN; + END IF; + + + IF p_sheet = 'SMETA' THEN + RETURN QUERY + SELECT + sm.row_type, + sm.depth, + ROW_NUMBER() OVER (ORDER BY sm.section_code) AS sort_order, + jsonb_build_object( + 'section_code', sm.section_code, + 'name', sm.name, + 'plan', jsonb_build_object( + 'support', jsonb_build_object('q1', sm.plan_supp_q1, 'q2', sm.plan_supp_q2, 'q3', sm.plan_supp_q3, 'q4', sm.plan_supp_q4, 'year', sm.plan_supp_year), + 'development', jsonb_build_object('q1', sm.plan_dev_q1, 'q2', sm.plan_dev_q2, 'q3', sm.plan_dev_q3, 'q4', sm.plan_dev_q4, 'year', sm.plan_dev_year) + ), + 'approved', jsonb_build_object( + 'support', jsonb_build_object('q1', sm.appr_supp_q1, 'q2', sm.appr_supp_q2, 'q3', sm.appr_supp_q3, 'q4', sm.appr_supp_q4, 'year', sm.appr_supp_year), + 'development', jsonb_build_object('q1', sm.appr_dev_q1, 'q2', sm.appr_dev_q2, 'q3', sm.appr_dev_q3, 'q4', sm.appr_dev_q4, 'year', sm.appr_dev_year) + ), + 'fact', jsonb_build_object( + 'support', jsonb_build_object('q1', sm.fact_supp_q1, 'q2', sm.fact_supp_q2, 'q3', sm.fact_supp_q3, 'q4', sm.fact_supp_q4, 'year', sm.fact_supp_year), + 'development', jsonb_build_object('q1', sm.fact_dev_q1, 'q2', sm.fact_dev_q2, 'q3', sm.fact_dev_q3, 'q4', sm.fact_dev_q4, 'year', sm.fact_dev_year) + ), + + + 'corrected', jsonb_build_object( + 'support', jsonb_build_object('q2', sm.corr_supp_q2, 'q3', sm.corr_supp_q3, 'q4', sm.corr_supp_q4), + 'development', jsonb_build_object('q2', sm.corr_dev_q2, 'q3', sm.corr_dev_q3, 'q4', sm.corr_dev_q4) + ) + ) + FROM v3.v_form2_smeta(p_form_id) sm + ORDER BY sm.section_code; + RETURN; + END IF; + + RAISE EXCEPTION 'Unknown sheet: %', p_sheet + USING HINT = 'Use AHR / CAP / OPER / AHR_LIMIT / AHR_RENT / AHR_UTILITY / AHR_SECURITY / OTCH9F / SMETA'; + +END; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.v_form1_view(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_direction character varying DEFAULT NULL::character varying, p_focus_lines integer[] DEFAULT NULL::integer[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql + STABLE +AS $function$ +BEGIN + IF p_sheet NOT IN ('AHR','CAP','OPER') THEN + RAISE EXCEPTION 'v_form1_view: unsupported sheet %', p_sheet; + END IF; + + RETURN QUERY + SELECT + j.row_type, + j.depth, + j._sort_rank AS sort_order, + jsonb_build_object( + 'line_id', j.line_id, + 'header', j.header, + 'plan', j.plan_data, + 'contract_summary', j.contract_summary, + 'allocation', j.allocation_data, + 'sequestration', j.sequestration_data, + 'reserve', j.reserve_data, + 'approved', j.approved_data, + 'collegial', j.collegial_data, + 'ckk', j.ckk_data, + 'contract_detail', j.contract_detail, + 'q1', j.q1_data, + 'q2', j.q2_data, + 'q3', j.q3_data, + 'q4', j.q4_data, + 'totals', j.totals_data + ) AS data + FROM v3.v_form1_sheet_jsonb(p_form_id, p_sheet, p_direction, p_sections, p_focus_lines) j + ORDER BY j._sort_rank; + RETURN; +END; +$function$ +; + +CREATE OR REPLACE FUNCTION v3.v_form_view(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_direction character varying DEFAULT NULL::character varying, p_user_id integer DEFAULT NULL::integer) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql + STABLE +AS $function$ +DECLARE + v_form_type VARCHAR; + v_year INT; + v_org_unit_id INT; + v_user_id INT; +BEGIN + SELECT form_type_code, year, org_unit_id + INTO v_form_type, v_year, v_org_unit_id + FROM v3.budget_form + WHERE id = p_form_id; + + IF NOT FOUND THEN + RAISE EXCEPTION 'budget_form id=% не существует в v3.budget_form', p_form_id; + END IF; + + v_user_id := p_user_id; + IF p_user_id IS NULL THEN + v_user_id := v3.current_user_id(); + END IF; + RETURN QUERY + SELECT + 'META'::VARCHAR, + -1, + 0::BIGINT, + jsonb_build_object( + 'user_id', v_user_id, + 'role', v3.user_role_code(v_user_id), + 'sheet', p_sheet, + 'editable', COALESCE( + (SELECT jsonb_agg( + jsonb_build_object('column', ec.column_key, + 'closes_at', ec.closes_at) + ORDER BY ec.column_key) + FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec), + '[]'::JSONB) + ); + + IF v_form_type = 'FORM_1' THEN + + IF p_sheet = 'SMETA' THEN + RETURN QUERY + SELECT + sm.row_type, + sm.depth, + ROW_NUMBER() OVER (ORDER BY sm.section_code) AS sort_order, + jsonb_build_object( + 'section_code', sm.section_code, + 'name', sm.name, + 'plan', jsonb_build_object( + 'support', jsonb_build_object('q1', sm.supp_plan_q1, 'q2', sm.supp_plan_q2, + 'q3', sm.supp_plan_q3, 'q4', sm.supp_plan_q4, + 'year', sm.supp_plan_year), + 'development', jsonb_build_object('q1', sm.dev_plan_q1, 'q2', sm.dev_plan_q2, + 'q3', sm.dev_plan_q3, 'q4', sm.dev_plan_q4, + 'year', sm.dev_plan_year), + 'total_year', sm.total_plan_year), + 'approved', jsonb_build_object( + 'support', jsonb_build_object('q1', sm.supp_appr_q1, 'q2', sm.supp_appr_q2, + 'q3', sm.supp_appr_q3, 'q4', sm.supp_appr_q4, + 'year', sm.supp_appr_year), + 'development', jsonb_build_object('q1', sm.dev_appr_q1, 'q2', sm.dev_appr_q2, + 'q3', sm.dev_appr_q3, 'q4', sm.dev_appr_q4, + 'year', sm.dev_appr_year), + 'total_year', sm.total_appr_year), + 'fact', jsonb_build_object( + 'support', jsonb_build_object('q1', sm.supp_act_q1, 'q2', sm.supp_act_q2, + 'q3', sm.supp_act_q3, 'q4', sm.supp_act_q4, + 'year', sm.supp_act_year), + 'development', jsonb_build_object('q1', sm.dev_act_q1, 'q2', sm.dev_act_q2, + 'q3', sm.dev_act_q3, 'q4', sm.dev_act_q4, + 'year', sm.dev_act_year), + 'total_year', sm.total_act_year), + 'corrected', jsonb_build_object( + 'support', jsonb_build_object('q2', sm.supp_corr_q2, 'q3', sm.supp_corr_q3, 'q4', sm.supp_corr_q4), + 'development', jsonb_build_object('q2', sm.dev_corr_q2, 'q3', sm.dev_corr_q3, 'q4', sm.dev_corr_q4)) + ) + FROM v3.v_form1_smeta(v_year, v_org_unit_id) sm + ORDER BY sm.section_code; + RETURN; + END IF; + + IF p_sheet IN ('AHR','CAP','OPER') THEN + RETURN QUERY SELECT * FROM v3.v_form1_view(p_form_id, p_sheet, p_sections, p_direction, NULL); + RETURN; + END IF; + + RAISE EXCEPTION 'Unknown FORM_1 sheet: %', p_sheet + USING HINT = 'Use AHR / CAP / OPER / SMETA'; + END IF; + + IF v_form_type = 'FORM_2' THEN + RETURN QUERY SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections); + RETURN; + END IF; + + IF v_form_type = 'FORM_4' THEN + RETURN QUERY SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections); + RETURN; + END IF; + + RAISE EXCEPTION 'Unsupported form_type=% for form_id=%', v_form_type, p_form_id; + +END; +$function$ +; + +CREATE OR REPLACE FUNCTION v3._form_affected_rows(p_form_id integer, p_sheet character varying, p_ids integer[], p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE plpgsql + STABLE + SET jit TO 'off' +AS $function$ +DECLARE + v_form_type VARCHAR; + v_strip TEXT[] := ARRAY[]::TEXT[]; + v_lc_path INT[]; + v_eid_set INT[]; + v_ei_path INT[]; +BEGIN + SELECT bf.form_type_code INTO v_form_type + FROM v3.budget_form bf + WHERE bf.id = p_form_id; + + IF p_sections IS NOT NULL THEN + SELECT COALESCE(array_agg(k), ARRAY[]::TEXT[]) + INTO v_strip + FROM unnest(ARRAY['plan','seq_dfip','seq_ssp','approved','contract','booking', + 'contract_summary','allocation','collegial','ckk', + 'sequestration','reserve','contract_detail', + 'q1','q2','q3','q4','totals', + 'fact_q1','fact_q2','fact_q3','fact_q4']) AS k + WHERE NOT (k = ANY(p_sections)); + END IF; + + IF v_form_type = 'FORM_1' AND p_sheet IN ('AHR','CAP','OPER') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form1_view(p_form_id, p_sheet, p_sections, p_direction, COALESCE(p_ids, '{}'::INT[])) v + ORDER BY v.sort_order; + RETURN; + ELSIF v_form_type = 'FORM_2' AND p_sheet IN ('AHR','CAP','OPER','AHR_RENT','AHR_UTILITY','AHR_SECURITY','AHR_LIMIT','OTCH9F') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form2_view(p_form_id, p_sheet, p_sections, COALESCE(p_ids, '{}'::INT[])) v + ORDER BY v.sort_order; + RETURN; + END IF; + + IF p_sheet IN ('AHR_RENT','AHR_UTILITY','AHR_SECURITY') THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE v.row_type = 'INPUT' AND (v.data->>'id')::INT = ANY(p_ids) + ORDER BY v.sort_order; + + ELSIF p_sheet = 'AHR_LIMIT' THEN + v_lc_path := v3._limit_template_path_set(p_ids); + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE (v.data->>'id')::INT = ANY(v_lc_path) + ORDER BY v.sort_order; + + ELSIF p_sheet = 'OTCH9F' THEN + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE EXISTS ( + SELECT 1 FROM v3.fixed_asset_report far + WHERE far.id = ANY(p_ids) + AND far.expense_item_id = (v.data->>'expense_item_id')::INT + AND far.equipment_name IS NOT DISTINCT FROM (v.data->>'equipment_name')) + ORDER BY v.sort_order; + + ELSE + SELECT array_agg(DISTINCT bl.expense_item_id) + INTO v_eid_set + FROM v3.budget_line bl + WHERE bl.id = ANY(p_ids); + v_ei_path := v3._expense_item_path_set(v_eid_set); + + IF v_form_type = 'FORM_4' THEN + RETURN QUERY + WITH vv AS MATERIALIZED ( + SELECT f.row_type, f.depth, f.sort_order, f.data + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) f + WHERE f.row_type <> 'META' + ), + chg AS ( + SELECT DISTINCT (x.data->'header'->>'program_id')::INT AS program_id, + (x.data->'header'->>'project_id')::INT AS project_id + FROM vv x + WHERE x.row_type = 'INPUT' AND (x.data->>'line_id')::INT = ANY(p_ids) + ) + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM vv v + WHERE (v.row_type = 'INPUT' AND (v.data->>'line_id')::INT = ANY(p_ids)) + OR (v.row_type = 'ROOT' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) + OR (v.row_type = 'GROUP' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) + AND (v.data->'header'->>'program_id')::INT IN (SELECT c.program_id FROM chg c)) + OR (v.row_type = 'ITEM' + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) + AND (v.data->'header'->>'project_id')::INT IN (SELECT c.project_id FROM chg c)) + ORDER BY v.sort_order; + ELSE + RETURN QUERY + SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip + FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v + WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM') + AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) + OR (v.row_type = 'INPUT' + AND (v.data->>'line_id')::INT = ANY(p_ids)) + ORDER BY v.sort_order; + END IF; + END IF; +END; +$function$ +; + + +CREATE OR REPLACE FUNCTION v3.get_form2_ahr_satellite_delta(p_form_id integer, p_source_sheet character varying, p_source_row_id integer) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE sql + STABLE + SET jit TO 'off' +AS $function$ + WITH target_lines AS ( + SELECT m.target_line_id AS line_id + FROM v3.form2_ahr_satellite_line_source m + JOIN v3.budget_line bl ON bl.id = m.target_line_id + WHERE m.source_sheet = p_source_sheet + AND m.source_id = p_source_row_id + AND bl.budget_form_id = p_form_id + AND p_source_sheet IN ('AHR_RENT', 'AHR_UTILITY', 'AHR_SECURITY') + + UNION + + SELECT bl.id AS line_id + FROM v3.limit_template lt + JOIN v3.expense_item ei + ON ei.sheet = 'AHR' + AND ei.direction = 'Support' + AND ( + (ei.depth = 3 AND ei.item_id = lt.expense_item_code) + OR ei.num_group_id = lt.expense_item_code + ) + JOIN v3.budget_line bl + ON bl.budget_form_id = p_form_id + AND bl.expense_item_id = ei.id + AND bl.name = regexp_replace( + lt.name, + '^[[:space:]]*-[[:space:]]*', + '' + ) + WHERE p_source_sheet = 'AHR_LIMIT' + AND lt.id = p_source_row_id + AND lt.row_type = 'LEAF' + ) + SELECT r.row_type, r.depth, r.sort_order, r.data + FROM v3._form_affected_rows( + p_form_id, 'AHR', + COALESCE((SELECT array_agg(tl.line_id) FROM target_lines tl), '{}'), + 'Support', NULL) r + ORDER BY r.sort_order; +$function$ +; diff --git a/api/alembic/versions/sql/0052_upd_form_cells_subtree.sql b/api/alembic/versions/sql/0052_upd_form_cells_subtree.sql deleted file mode 100644 index 2d09e32..0000000 --- a/api/alembic/versions/sql/0052_upd_form_cells_subtree.sql +++ /dev/null @@ -1,2791 +0,0 @@ --- AURORA-1850 (change: openspec/changes/aurora-1850-upd-form-cells-subtree): правка ячейки пересчитывает только затронутое поддерево. --- AURORA-1850: фокусные сборщики FORM_1/FORM_2, скелет с _sort_rank, _form_affected_rows и дельта AHR на фокусном пути, jit=off. - -DROP FUNCTION v3.v_form2_view(integer, character varying, text[]); -DROP FUNCTION v3.v_form2_sheet_jsonb(integer, character varying, text[]); -DROP FUNCTION v3.v_form2_sheet_sections(integer, character varying, text[]); -DROP FUNCTION v3.v_form1_sheet_jsonb(integer, character varying, character varying, text[]); -DROP FUNCTION v3.v_form1_sheet_sections(integer, character varying, character varying, text[]); - -CREATE OR REPLACE FUNCTION v3.v_form2_sheet_sections(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) - RETURNS TABLE(row_type character varying, depth integer, line_id integer, col_section_code character varying, col_item_id character varying, col_num_group_id character varying, col_name character varying, col_vsp_id integer, col_vsp_address character varying, col_plan_q1 numeric, col_plan_q2 numeric, col_plan_q3 numeric, col_plan_q4 numeric, col_plan_year numeric, col_plan_comment character varying, col_seq_dfip_q1 numeric, col_seq_dfip_q2 numeric, col_seq_dfip_q3 numeric, col_seq_dfip_q4 numeric, col_seq_dfip_year numeric, col_seq_dfip_just character varying, col_seq_ssp_q1 numeric, col_seq_ssp_q2 numeric, col_seq_ssp_q3 numeric, col_seq_ssp_q4 numeric, col_seq_ssp_year numeric, col_seq_ssp_just character varying, col_appr_q1 numeric, col_appr_q2 numeric, col_appr_q3 numeric, col_appr_q4 numeric, col_appr_year numeric, col_cd_counterparty character varying, col_cd_reference character varying, col_cd_date date, col_cd_subject character varying, col_cd_currency character varying, col_cd_ceiling numeric, col_cd_vat_rate character varying, col_cd_deadline character varying, col_cd_scheme character varying, col_cd_act character varying, col_cd_comment character varying, col_book_q1 numeric, col_book_q2 numeric, col_book_q3 numeric, col_book_q4 numeric, col_book_next_q1 numeric, col_book_next_q2 numeric, col_book_next_q3 numeric, col_book_next_q4 numeric, col_q1_adj_current numeric, col_q1_adj_ssp numeric, col_q1_adj_reserve numeric, col_q1_adj_comment character varying, col_q1_corrected_plan numeric, col_q1_pay_date date, col_q1_pay_amount numeric, col_q1_pay_comment character varying, col_q1_pay_act character varying, col_q1_booking numeric, col_q1_actual_m1 numeric, col_q1_actual_m2 numeric, col_q1_actual_m3 numeric, col_q1_actual_quarter numeric, col_q1_residual_after_booking numeric, col_q1_residual_after_actual numeric, col_q1_transfer_q2 numeric, col_q1_transfer_q2_delay_acts numeric, col_q1_transfer_q2_delay_procurement numeric, col_q1_transfer_q2_economy_rf numeric, col_q1_transfer_next_comment character varying, col_q1_transfer_q3 numeric, col_q1_transfer_q4 numeric, col_q1_transfer_far_comment character varying, col_q1_transfer_econ numeric, col_q1_total numeric, col_q2_target_change numeric, col_q2_base_correction numeric, col_q2_base_correction_comment character varying, col_q2_revision_inc numeric, col_q2_revision_seq numeric, col_q2_revision_comment character varying, col_q2_new_plan numeric, col_q2_adj_current numeric, col_q2_adj_ssp numeric, col_q2_adj_reserve numeric, col_q2_adj_comment character varying, col_q2_corrected_plan numeric, col_q2_pay_date date, col_q2_pay_amount numeric, col_q2_pay_comment character varying, col_q2_pay_act character varying, col_q2_booking numeric, col_q2_actual_m1 numeric, col_q2_actual_m2 numeric, col_q2_actual_m3 numeric, col_q2_actual_quarter numeric, col_q2_residual_after_booking numeric, col_q2_residual_after_actual numeric, col_q2_transfer_q3 numeric, col_q2_transfer_q3_delay_acts numeric, col_q2_transfer_q3_delay_procurement numeric, col_q2_transfer_q3_economy_rf numeric, col_q2_transfer_next_comment character varying, col_q2_transfer_q4 numeric, col_q2_transfer_far_comment character varying, col_q2_transfer_econ numeric, col_q2_total numeric, col_q3_target_change numeric, col_q3_base_correction numeric, col_q3_base_correction_comment character varying, col_q3_revision_inc numeric, col_q3_revision_seq numeric, col_q3_revision_comment character varying, col_q3_new_plan numeric, col_q3_adj_current numeric, col_q3_adj_ssp numeric, col_q3_adj_reserve numeric, col_q3_adj_comment character varying, col_q3_corrected_plan numeric, col_q3_pay_date date, col_q3_pay_amount numeric, col_q3_pay_comment character varying, col_q3_pay_act character varying, col_q3_booking numeric, col_q3_actual_m1 numeric, col_q3_actual_m2 numeric, col_q3_actual_m3 numeric, col_q3_actual_quarter numeric, col_q3_residual_after_booking numeric, col_q3_residual_after_actual numeric, col_q3_transfer_q4 numeric, col_q3_transfer_q4_delay_acts numeric, col_q3_transfer_q4_delay_procurement numeric, col_q3_transfer_q4_economy_rf numeric, col_q3_transfer_next_comment character varying, col_q3_transfer_econ numeric, col_q3_total numeric, col_q4_target_change numeric, col_q4_base_correction numeric, col_q4_base_correction_comment character varying, col_q4_revision_inc numeric, col_q4_revision_seq numeric, col_q4_revision_comment character varying, col_q4_new_plan numeric, col_q4_adj_current numeric, col_q4_adj_ssp numeric, col_q4_adj_reserve numeric, col_q4_adj_comment character varying, col_q4_corrected_plan numeric, col_q4_pay_date date, col_q4_pay_amount numeric, col_q4_pay_comment character varying, col_q4_pay_act character varying, col_q4_booking numeric, col_q4_actual_m1 numeric, col_q4_actual_m2 numeric, col_q4_actual_m3 numeric, col_q4_actual_spod numeric, col_q4_actual_quarter numeric, col_q4_residual_after_booking numeric, col_q4_residual_after_actual numeric, col_q4_transfer_econ numeric, col_q4_total numeric, col_fact_year numeric, col_pay_year numeric, col_economy_year numeric, col_internal_order character varying, col_cs_total numeric, col_cs_counterparty character varying, col_cs_deadline character varying, col_cs_comment character varying, col_cs_future_y1 numeric, col_cs_future_y2 numeric, col_cs_other_ssp numeric, col_al_contract_ref character varying, col_al_purpose character varying, col_al_order character varying, col_al_property character varying, col_ca_approved numeric, col_ca_protocol character varying, col_ca_note character varying, col_ckk_ceiling numeric, col_ckk_rf_sched character varying, col_ckk_deadline character varying, col_ckk_proc_plan character varying, col_ckk_proc_meth character varying, col_ckk_comment character varying, col_cd_addenda character varying, col_cd_exp_q1 numeric, col_cd_exp_q2 numeric, col_cd_exp_q3 numeric, col_cd_exp_q4 numeric, col_cd_rf_sched character varying, col_cd_exchange_rate numeric, col_cd_amount_foreign numeric, col_q1_adj_rf numeric, col_q1_pay_ho numeric, col_q1_pay_rf numeric, col_q2_adj_rf numeric, col_q2_pay_ho numeric, col_q2_pay_rf numeric, col_q3_adj_rf numeric, col_q3_pay_ho numeric, col_q3_pay_rf numeric, col_q4_adj_rf numeric, col_q4_pay_ho numeric, col_q4_pay_rf numeric, _sort_path integer[], _sort_rank bigint) - LANGUAGE plpgsql - STABLE - SET jit TO 'off' -AS $function$ -#variable_conflict use_column -DECLARE - s_plan BOOL; s_seq_d BOOL; s_seq_s BOOL; s_appr BOOL; - s_cd BOOL; s_book BOOL; - s_cs BOOL; s_al BOOL; s_ca BOOL; s_ckk BOOL; -- НОВЫЕ блоки - s_q1 BOOL; s_q2 BOOL; s_q3 BOOL; s_q4 BOOL; s_tot BOOL; - s_need_ap BOOL; -- plan/seq/reserve нужны для approved + cp1..cp4 - v_focus_nodes INT[]; -- AURORA-1850: узлы фокуса (путь статей строк фокуса ∩ tw); NULL = весь лист - v_focus_eids INT[]; -- AURORA-1850: объединение desc_ids узлов фокуса -BEGIN - s_plan := p_sections IS NULL OR 'plan' = ANY(p_sections); - s_seq_d := p_sections IS NULL OR 'seq_dfip' = ANY(p_sections); - s_seq_s := p_sections IS NULL OR 'seq_ssp' = ANY(p_sections); - s_appr := p_sections IS NULL OR 'approved' = ANY(p_sections); - s_cd := p_sections IS NULL OR 'contract' = ANY(p_sections); - s_book := p_sections IS NULL OR 'booking' = ANY(p_sections); - s_cs := p_sections IS NULL OR 'contract_summary' = ANY(p_sections); - s_al := p_sections IS NULL OR 'allocation' = ANY(p_sections); - s_ca := p_sections IS NULL OR 'collegial' = ANY(p_sections); - s_ckk := p_sections IS NULL OR 'ckk' = ANY(p_sections); - s_q1 := p_sections IS NULL OR 'q1' = ANY(p_sections); - s_q2 := p_sections IS NULL OR 'q2' = ANY(p_sections); - s_q3 := p_sections IS NULL OR 'q3' = ANY(p_sections); - s_q4 := p_sections IS NULL OR 'q4' = ANY(p_sections); - s_tot := p_sections IS NULL OR 'totals' = ANY(p_sections); - s_need_ap := s_plan OR s_appr OR s_q1 OR s_q2 OR s_q3 OR s_q4; - - -- Фокус (D1): NULL = весь лист, '{}' = пустой результат. COALESCE обязателен: - -- пустой фокус не должен превратиться в NULL и провалиться в полную сборку. - IF p_focus_lines IS NOT NULL THEN - WITH fp AS ( - SELECT v3._expense_item_path_set( - (SELECT array_agg(DISTINCT bl.expense_item_id) - FROM v3.budget_line bl - WHERE bl.id = ANY(p_focus_lines))) AS ids - ), - fn AS ( - SELECT t.id, t.desc_ids - FROM v3.mv_expense_item_tree t - JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id - JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code - WHERE t.sheet = p_sheet - AND t.id = ANY(COALESCE((SELECT fp.ids FROM fp), '{}'::int[])) - ) - SELECT COALESCE((SELECT array_agg(fn.id) FROM fn), '{}'::int[]), - COALESCE((SELECT array_agg(DISTINCT d) FROM fn, unnest(fn.desc_ids) AS d), '{}'::int[]) - INTO v_focus_nodes, v_focus_eids; - END IF; - - RETURN QUERY - WITH - tw AS ( - SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, - t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids, - p.parent_item_id AS grandparent_item_id - FROM v3.mv_expense_item_tree t - LEFT JOIN v3.mv_expense_item_tree p ON p.id = t.parent_id - JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id - JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code - WHERE t.sheet = p_sheet - ), - page AS ( - SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.name AS bname, bl.vsp_id, - bl.internal_order AS io - FROM v3.budget_line bl - JOIN v3.expense_item ei ON ei.id = bl.expense_item_id - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet - ), - tw_f AS ( - SELECT * FROM tw WHERE p_focus_lines IS NULL OR tw.id = ANY(v_focus_nodes) - ), - page_f AS ( - SELECT * FROM page WHERE p_focus_lines IS NULL OR page.lid = ANY(p_focus_lines) - ), - -- Скелет листа (D2): ключи всех узлов tw и всех строк page JOIN tw, без jsonb и сумм. - -- Ранг одинаков в обоих режимах; tie-break D6: узел раньше строки. - sk AS ( - SELECT n.k, - ROW_NUMBER() OVER (ORDER BY n._sort, n.lid NULLS FIRST) AS rnk - FROM ( - SELECT -t0.id::BIGINT AS k, NULL::INT AS lid, t0.path AS _sort FROM tw t0 - UNION ALL - SELECT pg0.lid::BIGINT, pg0.lid::INT, t1.path || ARRAY[pg0.lid::INT] - FROM page pg0 JOIN tw t1 ON t1.id = pg0.eid - ) n - ), - jp AS (SELECT p.* FROM v3.plan p JOIN page_f pg ON p.line_id = pg.lid WHERE s_need_ap), - jsd AS (SELECT s.* FROM v3.sequestration s JOIN page_f pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='DFIP'), - jsg AS (SELECT s.* FROM v3.sequestration s JOIN page_f pg ON s.line_id = pg.lid WHERE s_need_ap AND s.actor='SSP_GO'), - jr AS (SELECT r.* FROM v3.reserve r JOIN page_f pg ON r.line_id = pg.lid WHERE s_need_ap), - jcd AS (SELECT c.* FROM v3.contract_detail c JOIN page_f pg ON c.line_id = pg.lid WHERE s_cd), - jck AS (SELECT c.* FROM v3.ckk c JOIN page_f pg ON c.line_id = pg.lid WHERE s_book OR s_ckk), - jcs AS (SELECT c.* FROM v3.contract_summary c JOIN page_f pg ON c.line_id = pg.lid WHERE s_cs), - jal AS (SELECT a.* FROM v3.allocation a JOIN page_f pg ON a.line_id = pg.lid WHERE s_al), - jca AS (SELECT c.* FROM v3.collegial_approval c JOIN page_f pg ON c.line_id = pg.lid WHERE s_ca), - jq1 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE s_q1 AND q.quarter=1), - jq2 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE s_q2 AND q.quarter=2), - jq3 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE s_q3 AND q.quarter=3), - jq4 AS (SELECT q.* FROM v3.budget_line_quarter q JOIN page_f pg ON q.line_id = pg.lid WHERE (s_q4 OR s_tot) AND q.quarter=4), - - input_base AS ( - SELECT - pg.lid, pg.eid, pg.bname, pg.vsp_id, - v.address AS vsp_addr, - CASE - WHEN t.depth < 3 THEN t.item_id - WHEN t.depth = 3 THEN t.parent_item_id - WHEN t.depth = 4 THEN t.grandparent_item_id - END AS sc, - t.item_id AS ic, t.num_group_id AS ng, t.name AS ename, t.path AS tree_path, - COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2, - COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4, - p.comment AS pcmt, - COALESCE(sd.adj_q1,0) AS dq1, COALESCE(sd.adj_q2,0) AS dq2, - COALESCE(sd.adj_q3,0) AS dq3, COALESCE(sd.adj_q4,0) AS dq4, - sd.justification AS djust, - COALESCE(sg.adj_q1,0) AS gq1, COALESCE(sg.adj_q2,0) AS gq2, - COALESCE(sg.adj_q3,0) AS gq3, COALESCE(sg.adj_q4,0) AS gq4, - sg.justification AS gjust, - COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2, - COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4, - cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.contract_date AS cd_dt, - cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil, - cd.vat_rate AS cd_vat, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch, - cd.act AS cd_act, cd.comment AS cd_cmt, - ck.expenses_q1 AS bk1, ck.expenses_q2 AS bk2, ck.expenses_q3 AS bk3, ck.expenses_q4 AS bk4, - ck.expenses_next_year_q1 AS bn1, ck.expenses_next_year_q2 AS bn2, - ck.expenses_next_year_q3 AS bn3, ck.expenses_next_year_q4 AS bn4, - pg.io AS io, - cs.total_amount AS cs_total, cs.counterparty AS cs_cp, cs.deadline AS cs_dl, - cs.comment AS cs_cmt, cs.future_payments_y1 AS cs_fy1, cs.future_payments_y2 AS cs_fy2, - cs.other_ssp_amount AS cs_oth, - al.contract_ref AS al_cref, al.allocation_purpose AS al_purp, - al.internal_order AS al_io, al.property_object AS al_prop, - ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_proto, ca.note AS ca_note, - ck.ceiling_amount AS ckk_ceil, ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl, - ck.procurement_plan AS ckk_pplan, ck.procurement_method AS ckk_pmeth, ck.comment AS ckk_cmt, - cd.addenda AS cd_add, cd.expenses_q1 AS cd_e1, cd.expenses_q2 AS cd_e2, - cd.expenses_q3 AS cd_e3, cd.expenses_q4 AS cd_e4, cd.rf_schedule AS cd_rf, - cd.exchange_rate AS cd_rate, cd.amount_foreign AS cd_fx, - q1.adj_rf AS q1_arf, q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, - q2.adj_rf AS q2_arf, q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf, - q3.adj_rf AS q3_arf, q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf, - q4.adj_rf AS q4_arf, q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf, - q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_reserve AS q1_arv, q1.adj_comment AS q1_acmt, - q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa, - q1.payment_comment AS q1_pcmt, - q1.payment_act AS q1_pact, - COALESCE( - q1.booking_amount, - CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q1 - WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1 - ELSE cd.expenses_q1 - END - - ) AS q1_book, - q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3, - q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4, - q1.transfer_to_economy AS q1_te, - q1.transfer_delay_acts AS q1_tda, q1.transfer_delay_procurement AS q1_tdp, - q1.transfer_economy_rf AS q1_terf, - q1.transfer_next_comment AS q1_tnc, q1.transfer_far_comment AS q1_tfc, - q2.target_change AS q2_tc, q2.base_plan_correction AS q2_bc, q2.base_plan_correction_comment AS q2_bcc, - q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq, - q2.plan_revision_comment AS q2_rcmt, - q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_reserve AS q2_arv, - q2.adj_comment AS q2_acmt, - q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa, - q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact, - COALESCE( - q2.booking_amount, - CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q2 - WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2 - ELSE cd.expenses_q2 - END - - ) AS q2_book, - q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3, - q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, q2.transfer_to_economy AS q2_te, - q2.transfer_delay_acts AS q2_tda, q2.transfer_delay_procurement AS q2_tdp, - q2.transfer_economy_rf AS q2_terf, - q2.transfer_next_comment AS q2_tnc, q2.transfer_far_comment AS q2_tfc, - q3.target_change AS q3_tc, q3.base_plan_correction AS q3_bc, - q3.base_plan_correction_comment AS q3_bcc, - q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq, - q3.plan_revision_comment AS q3_rcmt, - q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_reserve AS q3_arv, - q3.adj_comment AS q3_acmt, - q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa, - q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact, - COALESCE( - q3.booking_amount, - CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q3 - WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3 - ELSE cd.expenses_q3 - END - - ) AS q3_book, - q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3, - q3.transfer_to_q4 AS q3_tq4, q3.transfer_to_economy AS q3_te, - q3.transfer_delay_acts AS q3_tda, q3.transfer_delay_procurement AS q3_tdp, - q3.transfer_economy_rf AS q3_terf, q3.transfer_next_comment AS q3_tnc, - q4.target_change AS q4_tc, q4.base_plan_correction AS q4_bc, - q4.base_plan_correction_comment AS q4_bcc, - q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq, - q4.plan_revision_comment AS q4_rcmt, - q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_reserve AS q4_arv, - q4.adj_comment AS q4_acmt, - q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa, - q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact, - COALESCE( - q4.booking_amount, - CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q4 - WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4 - ELSE cd.expenses_q4 - END - - ) AS q4_book, - q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, q4.actual_spod AS q4_spod, - q4.transfer_to_economy AS q4_te, - COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(sg.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1, - COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(sg.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2, - COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(sg.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3, - COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(sg.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4 - FROM page_f pg - JOIN tw t ON t.id = pg.eid - LEFT JOIN v3.vsp v ON v.id = pg.vsp_id - LEFT JOIN jp p ON p.line_id = pg.lid - LEFT JOIN jsd sd ON sd.line_id = pg.lid - LEFT JOIN jsg sg ON sg.line_id = pg.lid - LEFT JOIN jr r ON r.line_id = pg.lid - LEFT JOIN jcd cd ON cd.line_id = pg.lid - LEFT JOIN jck ck ON ck.line_id = pg.lid - LEFT JOIN jcs cs ON cs.line_id = pg.lid - LEFT JOIN jal al ON al.line_id = pg.lid - LEFT JOIN jca ca ON ca.line_id = pg.lid - LEFT JOIN jq1 q1 ON q1.line_id = pg.lid - LEFT JOIN jq2 q2 ON q2.line_id = pg.lid - LEFT JOIN jq3 q3 ON q3.line_id = pg.lid - LEFT JOIN jq4 q4 ON q4.line_id = pg.lid - ), - enriched AS ( - SELECT b.*, - b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_arv,0) AS cp1, - COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1, - b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) + COALESCE(b.q2_bc,0) AS np2, - COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2, - b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) + COALESCE(b.q3_bc,0) AS np3, - COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3, - b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) + COALESCE(b.q4_bc,0) AS np4, - COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4 - FROM input_base b - ), - final_input AS ( - SELECT e.*, - e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_arv,0) AS cp2, - e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_arv,0) AS cp3, - e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_arv,0) AS cp4 - FROM enriched e - ), - - agg AS ( - SELECT bl.expense_item_id AS eid, - SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4, - SUM(sd.adj_q1) AS sd1, SUM(sd.adj_q2) AS sd2, SUM(sd.adj_q3) AS sd3, SUM(sd.adj_q4) AS sd4, - SUM(sg.adj_q1) AS sg1, SUM(sg.adj_q2) AS sg2, SUM(sg.adj_q3) AS sg3, SUM(sg.adj_q4) AS sg4, - SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4, - SUM(ck.expenses_q1) AS bk1, SUM(ck.expenses_q2) AS bk2, SUM(ck.expenses_q3) AS bk3, SUM(ck.expenses_q4) AS bk4, - SUM(cd.expenses_q1) AS bkc1, SUM(cd.expenses_q2) AS bkc2, SUM(cd.expenses_q3) AS bkc3, SUM(cd.expenses_q4) AS bkc4, - SUM(ck.expenses_next_year_q1) AS bn1, SUM(ck.expenses_next_year_q2) AS bn2, - SUM(ck.expenses_next_year_q3) AS bn3, SUM(ck.expenses_next_year_q4) AS bn4 - FROM v3.budget_line bl - JOIN v3.expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN v3.plan p ON p.line_id = bl.id AND s_need_ap - LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor='DFIP' AND s_need_ap - LEFT JOIN v3.sequestration sg ON sg.line_id = bl.id AND sg.actor='SSP_GO' AND s_need_ap - LEFT JOIN v3.reserve r ON r.line_id = bl.id AND s_need_ap - LEFT JOIN v3.ckk ck ON ck.line_id = bl.id AND s_book - LEFT JOIN v3.contract_detail cd ON cd.line_id = bl.id AND s_cd - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet - AND (s_need_ap OR s_book OR s_cd) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id - ), - aq_q AS ( - SELECT bl.expense_item_id AS eid, qrtrs.qrtr as quarter, - SUM(q.adj_current) AS ac, SUM(q.adj_ssp) AS as_v, SUM(q.adj_reserve) AS arv, - SUM(q.payment_amount) AS pa, - SUM( - COALESCE( - q.booking_amount, - CASE - WHEN qrtrs.qrtr = 1 - THEN CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q1 - WHEN ck.expenses_q1 > 0 THEN ck.expenses_q1 - ELSE cd.expenses_q1 - END - WHEN qrtrs.qrtr = 2 THEN CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q2 - WHEN ck.expenses_q2 > 0 THEN ck.expenses_q2 - ELSE cd.expenses_q2 - END - WHEN qrtrs.qrtr = 3 THEN CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q3 - WHEN ck.expenses_q3 > 0 THEN ck.expenses_q3 - ELSE cd.expenses_q3 - END - WHEN qrtrs.qrtr = 4 THEN CASE - WHEN p_sheet = 'AHR' THEN ck.expenses_q4 - WHEN ck.expenses_q4 > 0 THEN ck.expenses_q4 - ELSE cd.expenses_q4 - END - END - - )) AS bk, - SUM(q.actual_m1) AS m1, SUM(q.actual_m2) AS m2, SUM(q.actual_m3) AS m3, - SUM(q.actual_spod) AS spod, - SUM(q.transfer_to_q2) AS tq2, SUM(q.transfer_to_q3) AS tq3, SUM(q.transfer_to_q4) AS tq4, - SUM(q.transfer_to_economy) AS te, - SUM(q.transfer_delay_acts) AS tda, - SUM(q.transfer_delay_procurement) AS tdp, - SUM(q.transfer_economy_rf) AS terf, - SUM(COALESCE(q.plan_revision_increase,0) - + COALESCE(q.plan_revision_sequester,0) - + COALESCE(q.target_change,0) - + COALESCE(q.base_plan_correction,0)) AS rev - FROM v3.budget_line bl - CROSS JOIN (VALUES (1), (2), (3), (4)) AS qrtrs(qrtr) - - JOIN v3.expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN v3.budget_line_quarter q ON q.line_id = bl.id AND q.quarter = qrtrs.qrtr - LEFT JOIN v3.ckk ck ON bl.id = ck.line_id - LEFT JOIN v3.contract_detail cd ON bl.id = cd.line_id - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id, qrtrs.qrtr - ), - tw_agg AS ( - SELECT tw.id, - SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4, - SUM(a.sd1) AS sd1, SUM(a.sd2) AS sd2, SUM(a.sd3) AS sd3, SUM(a.sd4) AS sd4, - SUM(a.sg1) AS sg1, SUM(a.sg2) AS sg2, SUM(a.sg3) AS sg3, SUM(a.sg4) AS sg4, - SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4, - SUM(a.bk1) AS bk1, SUM(a.bk2) AS bk2, SUM(a.bk3) AS bk3, SUM(a.bk4) AS bk4, - SUM(a.bkc1) AS bkc1, SUM(a.bkc2) AS bkc2, SUM(a.bkc3) AS bkc3, SUM(a.bkc4) AS bkc4, - SUM(a.bn1) AS bn1, SUM(a.bn2) AS bn2, SUM(a.bn3) AS bn3, SUM(a.bn4) AS bn4 - FROM tw_f tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids) - GROUP BY tw.id - ), - tw_aq1 AS ( - SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.bk) AS bk, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, - SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf - FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=1 GROUP BY tw.id - ), - tw_aq2 AS ( - SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.bk) AS bk, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev, - SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf - FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=2 GROUP BY tw.id - ), - tw_aq3 AS ( - SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.bk) AS bk, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.tq4) AS tq4, SUM(b.te) AS te, SUM(b.rev) AS rev, - SUM(b.tda) AS tda, SUM(b.tdp) AS tdp, SUM(b.terf) AS terf - FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=3 GROUP BY tw.id - ), - tw_aq4 AS ( - SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as_v) AS as_v, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.bk) AS bk, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, SUM(b.spod) AS spod, - SUM(b.te) AS te, SUM(b.rev) AS rev - FROM tw_f tw LEFT JOIN aq_q b ON b.eid = ANY(tw.desc_ids) AND b.quarter=4 GROUP BY tw.id - ) - - SELECT sub.row_type, sub.depth, sub.line_id, sub.col_section_code, sub.col_item_id, sub.col_num_group_id, sub.col_name, sub.col_vsp_id, sub.col_vsp_address, sub.col_plan_q1, sub.col_plan_q2, sub.col_plan_q3, sub.col_plan_q4, sub.col_plan_year, sub.col_plan_comment, sub.col_seq_dfip_q1, sub.col_seq_dfip_q2, sub.col_seq_dfip_q3, sub.col_seq_dfip_q4, sub.col_seq_dfip_year, sub.col_seq_dfip_just, sub.col_seq_ssp_q1, sub.col_seq_ssp_q2, sub.col_seq_ssp_q3, sub.col_seq_ssp_q4, sub.col_seq_ssp_year, sub.col_seq_ssp_just, sub.col_appr_q1, sub.col_appr_q2, sub.col_appr_q3, sub.col_appr_q4, sub.col_appr_year, sub.col_cd_counterparty, sub.col_cd_reference, sub.col_cd_date, sub.col_cd_subject, sub.col_cd_currency, sub.col_cd_ceiling, sub.col_cd_vat_rate, sub.col_cd_deadline, sub.col_cd_scheme, sub.col_cd_act, sub.col_cd_comment, sub.col_book_q1, sub.col_book_q2, sub.col_book_q3, sub.col_book_q4, sub.col_book_next_q1, sub.col_book_next_q2, sub.col_book_next_q3, sub.col_book_next_q4, sub.col_q1_adj_current, sub.col_q1_adj_ssp, sub.col_q1_adj_reserve, sub.col_q1_adj_comment, sub.col_q1_corrected_plan, sub.col_q1_pay_date, sub.col_q1_pay_amount, sub.col_q1_pay_comment, sub.col_q1_pay_act, sub.col_q1_booking, sub.col_q1_actual_m1, sub.col_q1_actual_m2, sub.col_q1_actual_m3, sub.col_q1_actual_quarter, sub.col_q1_residual_after_booking, sub.col_q1_residual_after_actual, sub.col_q1_transfer_q2, sub.col_q1_transfer_q2_delay_acts, sub.col_q1_transfer_q2_delay_procurement, sub.col_q1_transfer_q2_economy_rf, sub.col_q1_transfer_next_comment, sub.col_q1_transfer_q3, sub.col_q1_transfer_q4, sub.col_q1_transfer_far_comment, sub.col_q1_transfer_econ, sub.col_q1_total, sub.col_q2_target_change, sub.col_q2_base_correction, sub.col_q2_base_correction_comment, sub.col_q2_revision_inc, sub.col_q2_revision_seq, sub.col_q2_revision_comment, sub.col_q2_new_plan, sub.col_q2_adj_current, sub.col_q2_adj_ssp, sub.col_q2_adj_reserve, sub.col_q2_adj_comment, sub.col_q2_corrected_plan, sub.col_q2_pay_date, sub.col_q2_pay_amount, sub.col_q2_pay_comment, sub.col_q2_pay_act, sub.col_q2_booking, sub.col_q2_actual_m1, sub.col_q2_actual_m2, sub.col_q2_actual_m3, sub.col_q2_actual_quarter, sub.col_q2_residual_after_booking, sub.col_q2_residual_after_actual, sub.col_q2_transfer_q3, sub.col_q2_transfer_q3_delay_acts, sub.col_q2_transfer_q3_delay_procurement, sub.col_q2_transfer_q3_economy_rf, sub.col_q2_transfer_next_comment, sub.col_q2_transfer_q4, sub.col_q2_transfer_far_comment, sub.col_q2_transfer_econ, sub.col_q2_total, sub.col_q3_target_change, sub.col_q3_base_correction, sub.col_q3_base_correction_comment, sub.col_q3_revision_inc, sub.col_q3_revision_seq, sub.col_q3_revision_comment, sub.col_q3_new_plan, sub.col_q3_adj_current, sub.col_q3_adj_ssp, sub.col_q3_adj_reserve, sub.col_q3_adj_comment, sub.col_q3_corrected_plan, sub.col_q3_pay_date, sub.col_q3_pay_amount, sub.col_q3_pay_comment, sub.col_q3_pay_act, sub.col_q3_booking, sub.col_q3_actual_m1, sub.col_q3_actual_m2, sub.col_q3_actual_m3, sub.col_q3_actual_quarter, sub.col_q3_residual_after_booking, sub.col_q3_residual_after_actual, sub.col_q3_transfer_q4, sub.col_q3_transfer_q4_delay_acts, sub.col_q3_transfer_q4_delay_procurement, sub.col_q3_transfer_q4_economy_rf, sub.col_q3_transfer_next_comment, sub.col_q3_transfer_econ, sub.col_q3_total, sub.col_q4_target_change, sub.col_q4_base_correction, sub.col_q4_base_correction_comment, sub.col_q4_revision_inc, sub.col_q4_revision_seq, sub.col_q4_revision_comment, sub.col_q4_new_plan, sub.col_q4_adj_current, sub.col_q4_adj_ssp, sub.col_q4_adj_reserve, sub.col_q4_adj_comment, sub.col_q4_corrected_plan, sub.col_q4_pay_date, sub.col_q4_pay_amount, sub.col_q4_pay_comment, sub.col_q4_pay_act, sub.col_q4_booking, sub.col_q4_actual_m1, sub.col_q4_actual_m2, sub.col_q4_actual_m3, sub.col_q4_actual_spod, sub.col_q4_actual_quarter, sub.col_q4_residual_after_booking, sub.col_q4_residual_after_actual, sub.col_q4_transfer_econ, sub.col_q4_total, sub.col_fact_year, sub.col_pay_year, sub.col_economy_year, sub.col_internal_order, sub.col_cs_total, sub.col_cs_counterparty, sub.col_cs_deadline, sub.col_cs_comment, sub.col_cs_future_y1, sub.col_cs_future_y2, sub.col_cs_other_ssp, sub.col_al_contract_ref, sub.col_al_purpose, sub.col_al_order, sub.col_al_property, sub.col_ca_approved, sub.col_ca_protocol, sub.col_ca_note, sub.col_ckk_ceiling, sub.col_ckk_rf_sched, sub.col_ckk_deadline, sub.col_ckk_proc_plan, sub.col_ckk_proc_meth, sub.col_ckk_comment, sub.col_cd_addenda, sub.col_cd_exp_q1, sub.col_cd_exp_q2, sub.col_cd_exp_q3, sub.col_cd_exp_q4, sub.col_cd_rf_sched, sub.col_cd_exchange_rate, sub.col_cd_amount_foreign, sub.col_q1_adj_rf, sub.col_q1_pay_ho, sub.col_q1_pay_rf, sub.col_q2_adj_rf, sub.col_q2_pay_ho, sub.col_q2_pay_rf, sub.col_q3_adj_rf, sub.col_q3_pay_ho, sub.col_q3_pay_rf, sub.col_q4_adj_rf, sub.col_q4_pay_ho, sub.col_q4_pay_rf, sub._sort_path, sk.rnk - FROM ( - SELECT - 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid::INT, - f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.vsp_id, f.vsp_addr, - CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END, - CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END, - CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END, - CASE WHEN s_seq_d THEN f.dq1 END, CASE WHEN s_seq_d THEN f.dq2 END, - CASE WHEN s_seq_d THEN f.dq3 END, CASE WHEN s_seq_d THEN f.dq4 END, - CASE WHEN s_seq_d THEN f.dq1+f.dq2+f.dq3+f.dq4 END, CASE WHEN s_seq_d THEN f.djust END, - CASE WHEN s_seq_s THEN f.gq1 END, CASE WHEN s_seq_s THEN f.gq2 END, - CASE WHEN s_seq_s THEN f.gq3 END, CASE WHEN s_seq_s THEN f.gq4 END, - CASE WHEN s_seq_s THEN f.gq1+f.gq2+f.gq3+f.gq4 END, CASE WHEN s_seq_s THEN f.gjust END, - CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END, - CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END, - CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END, - CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END, - CASE WHEN s_cd THEN f.cd_dt END, CASE WHEN s_cd THEN f.cd_subj END, - CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END, - CASE WHEN s_cd THEN f.cd_vat END, CASE WHEN s_cd THEN f.cd_dl END, - CASE WHEN s_cd THEN f.cd_sch END, CASE WHEN s_cd THEN f.cd_act END, - CASE WHEN s_cd THEN f.cd_cmt END, - CASE WHEN s_book THEN f.bk1 END, CASE WHEN s_book THEN f.bk2 END, - CASE WHEN s_book THEN f.bk3 END, CASE WHEN s_book THEN f.bk4 END, - CASE WHEN s_book THEN f.bn1 END, CASE WHEN s_book THEN f.bn2 END, - CASE WHEN s_book THEN f.bn3 END, CASE WHEN s_book THEN f.bn4 END, - CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, CASE WHEN s_q1 THEN f.q1_arv END, - CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END, - CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END, - CASE WHEN s_q1 THEN f.q1_pcmt END, - CASE WHEN s_q1 THEN f.q1_pact END, CASE WHEN s_q1 THEN f.q1_book END, - CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END, - CASE WHEN s_q1 THEN f.aq1 END, - CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.q1_book,0) END, -- residual_after_booking - CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, -- residual_after_actual - CASE WHEN s_q1 THEN f.q1_tq2 END, - CASE WHEN s_q1 THEN f.q1_tda END, CASE WHEN s_q1 THEN f.q1_tdp END, CASE WHEN s_q1 THEN f.q1_terf END, - CASE WHEN s_q1 THEN f.q1_tnc END, - CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END, - CASE WHEN s_q1 THEN f.q1_tfc END, - CASE WHEN s_q1 THEN f.q1_te END, - CASE WHEN s_q1 THEN - COALESCE(f.q1_tda,0)+COALESCE(f.q1_tdp,0)+COALESCE(f.q1_terf,0) - +COALESCE(f.q1_tq3,0)+COALESCE(f.q1_tq4,0)+COALESCE(f.q1_te,0) - END, - CASE WHEN s_q2 THEN f.q2_tc END, CASE WHEN s_q2 THEN f.q2_bc END, CASE WHEN s_q2 THEN f.q2_bcc END, - CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END, - CASE WHEN s_q2 THEN f.q2_rcmt END, - CASE WHEN s_q2 THEN f.np2 END, - CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, CASE WHEN s_q2 THEN f.q2_arv END, - CASE WHEN s_q2 THEN f.q2_acmt END, - CASE WHEN s_q2 THEN f.cp2 END, - CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END, - CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END, - CASE WHEN s_q2 THEN f.q2_book END, - CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END, - CASE WHEN s_q2 THEN f.aq2 END, - CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.q2_book,0) END, - CASE WHEN s_q2 THEN f.cp2 - f.aq2 END, - CASE WHEN s_q2 THEN f.q2_tq3 END, - CASE WHEN s_q2 THEN f.q2_tda END, CASE WHEN s_q2 THEN f.q2_tdp END, CASE WHEN s_q2 THEN f.q2_terf END, - CASE WHEN s_q2 THEN f.q2_tnc END, - CASE WHEN s_q2 THEN f.q2_tq4 END, - CASE WHEN s_q2 THEN f.q2_tfc END, - CASE WHEN s_q2 THEN f.q2_te END, - CASE WHEN s_q2 THEN - COALESCE(f.q2_tda,0)+COALESCE(f.q2_tdp,0)+COALESCE(f.q2_terf,0) - +COALESCE(f.q2_tq4,0)+COALESCE(f.q2_te,0) - END, - CASE WHEN s_q3 THEN f.q3_tc END, CASE WHEN s_q3 THEN f.q3_bc END, - CASE WHEN s_q3 THEN f.q3_bcc END, - CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END, - CASE WHEN s_q3 THEN f.q3_rcmt END, - CASE WHEN s_q3 THEN f.np3 END, - CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, CASE WHEN s_q3 THEN f.q3_arv END, - CASE WHEN s_q3 THEN f.q3_acmt END, - CASE WHEN s_q3 THEN f.cp3 END, - CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END, - CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END, - CASE WHEN s_q3 THEN f.q3_book END, - CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END, - CASE WHEN s_q3 THEN f.aq3 END, - CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.q3_book,0) END, - CASE WHEN s_q3 THEN f.cp3 - f.aq3 END, - CASE WHEN s_q3 THEN f.q3_tq4 END, - CASE WHEN s_q3 THEN f.q3_tda END, CASE WHEN s_q3 THEN f.q3_tdp END, CASE WHEN s_q3 THEN f.q3_terf END, - CASE WHEN s_q3 THEN f.q3_tnc END, - CASE WHEN s_q3 THEN f.q3_te END, - CASE WHEN s_q3 THEN - COALESCE(f.q3_tda,0)+COALESCE(f.q3_tdp,0)+COALESCE(f.q3_terf,0) - +COALESCE(f.q3_te,0) - END, - CASE WHEN s_q4 THEN f.q4_tc END, CASE WHEN s_q4 THEN f.q4_bc END, - CASE WHEN s_q4 THEN f.q4_bcc END, - CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END, - CASE WHEN s_q4 THEN f.q4_rcmt END, - CASE WHEN s_q4 THEN f.np4 END, - CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, CASE WHEN s_q4 THEN f.q4_arv END, - CASE WHEN s_q4 THEN f.q4_acmt END, - CASE WHEN s_q4 THEN f.cp4 END, - CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END, - CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END, - CASE WHEN s_q4 THEN f.q4_book END, - CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END, - CASE WHEN s_q4 THEN f.q4_spod END, - CASE WHEN s_q4 THEN f.aq4 END, - CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.q4_book,0) END, - CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, - CASE WHEN s_q4 THEN f.q4_te END, - CASE WHEN s_q4 THEN f.q4_te END, - CASE WHEN s_tot THEN f.aq1+f.aq2+f.aq3+f.aq4 END, - CASE WHEN s_tot THEN COALESCE(f.q1_pa,0)+COALESCE(f.q2_pa,0)+COALESCE(f.q3_pa,0)+COALESCE(f.q4_pa,0) END, - CASE WHEN s_tot THEN f.cp4 - f.aq4 END, - - f.io, - CASE WHEN s_cs THEN f.cs_total END, CASE WHEN s_cs THEN f.cs_cp END, - CASE WHEN s_cs THEN f.cs_dl END, CASE WHEN s_cs THEN f.cs_cmt END, - CASE WHEN s_cs THEN f.cs_fy1 END, CASE WHEN s_cs THEN f.cs_fy2 END, - CASE WHEN s_cs THEN f.cs_oth END, - CASE WHEN s_al THEN f.al_cref END, CASE WHEN s_al THEN f.al_purp END, - CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_prop END, - CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_proto END, - CASE WHEN s_ca THEN f.ca_note END, - CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk_rf END, - CASE WHEN s_ckk THEN f.ckk_dl END, CASE WHEN s_ckk THEN f.ckk_pplan END, - CASE WHEN s_ckk THEN f.ckk_pmeth END, CASE WHEN s_ckk THEN f.ckk_cmt END, - CASE WHEN s_cd THEN f.cd_add END, CASE WHEN s_cd THEN f.cd_e1 END, - CASE WHEN s_cd THEN f.cd_e2 END, CASE WHEN s_cd THEN f.cd_e3 END, - CASE WHEN s_cd THEN f.cd_e4 END, CASE WHEN s_cd THEN f.cd_rf END, - CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END, - CASE WHEN s_q1 THEN f.q1_arf END, CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, - CASE WHEN s_q2 THEN f.q2_arf END, CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END, - CASE WHEN s_q3 THEN f.q3_arf END, CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END, - CASE WHEN s_q4 THEN f.q4_arf END, CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END, - - f.tree_path || ARRAY[f.lid::INT] AS _sort, - f.lid::BIGINT AS _k - FROM final_input f - - UNION ALL - - SELECT - CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR, - t.depth, NULL::INT, - CASE - WHEN t.depth < 3 THEN t.item_id - WHEN t.depth = 3 THEN t.parent_item_id - WHEN t.depth = 4 THEN t.grandparent_item_id - END, - CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL END, - t.num_group_id, t.name, NULL::INT, NULL::VARCHAR, - CASE WHEN s_plan THEN ta.sp1 END, CASE WHEN s_plan THEN ta.sp2 END, - CASE WHEN s_plan THEN ta.sp3 END, CASE WHEN s_plan THEN ta.sp4 END, - CASE WHEN s_plan THEN COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) END, - NULL::VARCHAR, - CASE WHEN s_seq_d THEN ta.sd1 END, CASE WHEN s_seq_d THEN ta.sd2 END, - CASE WHEN s_seq_d THEN ta.sd3 END, CASE WHEN s_seq_d THEN ta.sd4 END, - CASE WHEN s_seq_d THEN COALESCE(ta.sd1,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sd4,0) END, - NULL::VARCHAR, - CASE WHEN s_seq_s THEN ta.sg1 END, CASE WHEN s_seq_s THEN ta.sg2 END, - CASE WHEN s_seq_s THEN ta.sg3 END, CASE WHEN s_seq_s THEN ta.sg4 END, - CASE WHEN s_seq_s THEN COALESCE(ta.sg1,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sg4,0) END, - NULL::VARCHAR, - CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) END, - CASE WHEN s_appr THEN COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) END, - CASE WHEN s_appr THEN COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) END, - CASE WHEN s_appr THEN COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END, - CASE WHEN s_appr THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0) - +COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0) - +COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0) - +COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) END, - NULL::VARCHAR, NULL::VARCHAR, NULL::DATE, NULL::VARCHAR, - NULL::VARCHAR, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, - NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_book THEN ta.bk1 END, CASE WHEN s_book THEN ta.bk2 END, - CASE WHEN s_book THEN ta.bk3 END, CASE WHEN s_book THEN ta.bk4 END, - CASE WHEN s_book THEN ta.bn1 END, CASE WHEN s_book THEN ta.bn2 END, - CASE WHEN s_book THEN ta.bn3 END, CASE WHEN s_book THEN ta.bn4 END, - CASE WHEN s_q1 THEN tb1.ac END, CASE WHEN s_q1 THEN tb1.as_v END, CASE WHEN s_q1 THEN tb1.arv END, - NULL::VARCHAR, - CASE WHEN s_q1 THEN COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0) END, - NULL::DATE, - CASE WHEN s_q1 THEN tb1.pa END, - NULL::VARCHAR, -- pay_comment - NULL::VARCHAR, -- pay_act - CASE WHEN s_q1 THEN tb1.bk END, -- booking (rollup) - CASE WHEN s_q1 THEN tb1.m1 END, CASE WHEN s_q1 THEN tb1.m2 END, CASE WHEN s_q1 THEN tb1.m3 END, - CASE WHEN s_q1 THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) END, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0)) - - COALESCE(tb1.bk,0) - END, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.sd1,0)+COALESCE(ta.sg1,0)+COALESCE(ta.sr1,0)+COALESCE(tb1.ac,0)+COALESCE(tb1.as_v,0)+COALESCE(tb1.arv,0)) - - (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)) - END, - CASE WHEN s_q1 THEN tb1.tq2 END, - CASE WHEN s_q1 THEN tb1.tda END, CASE WHEN s_q1 THEN tb1.tdp END, CASE WHEN s_q1 THEN tb1.terf END, - NULL::VARCHAR, -- transfer_next_comment (text, no rollup) - CASE WHEN s_q1 THEN tb1.tq3 END, CASE WHEN s_q1 THEN tb1.tq4 END, - NULL::VARCHAR, -- far comment - CASE WHEN s_q1 THEN tb1.te END, - CASE WHEN s_q1 THEN - COALESCE(tb1.tda,0)+COALESCE(tb1.tdp,0)+COALESCE(tb1.terf,0) - +COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)+COALESCE(tb1.te,0) - END, - NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction - NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq - NULL::VARCHAR, -- revision_comment - CASE WHEN s_q2 THEN - COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0) - END, - CASE WHEN s_q2 THEN tb2.ac END, CASE WHEN s_q2 THEN tb2.as_v END, CASE WHEN s_q2 THEN tb2.arv END, - NULL::VARCHAR, -- adj_comment - CASE WHEN s_q2 THEN - COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0) - END, - NULL::DATE, - CASE WHEN s_q2 THEN tb2.pa END, - NULL::VARCHAR, -- pay_comment - NULL::VARCHAR, -- pay_act - CASE WHEN s_q2 THEN tb2.bk END, -- booking (rollup) - CASE WHEN s_q2 THEN tb2.m1 END, CASE WHEN s_q2 THEN tb2.m2 END, CASE WHEN s_q2 THEN tb2.m3 END, - CASE WHEN s_q2 THEN COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) END, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)) - - COALESCE(tb2.bk,0) - END, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.sd2,0)+COALESCE(ta.sg2,0)+COALESCE(ta.sr2,0)+COALESCE(tb1.tq2,0)+COALESCE(tb2.rev,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as_v,0)+COALESCE(tb2.arv,0)) - - (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)) - END, - CASE WHEN s_q2 THEN tb2.tq3 END, - CASE WHEN s_q2 THEN tb2.tda END, CASE WHEN s_q2 THEN tb2.tdp END, CASE WHEN s_q2 THEN tb2.terf END, - NULL::VARCHAR, -- transfer_next_comment (text, no rollup) - CASE WHEN s_q2 THEN tb2.tq4 END, - NULL::VARCHAR, -- far comment - CASE WHEN s_q2 THEN tb2.te END, - CASE WHEN s_q2 THEN - COALESCE(tb2.tda,0)+COALESCE(tb2.tdp,0)+COALESCE(tb2.terf,0) - +COALESCE(tb2.tq4,0)+COALESCE(tb2.te,0) - END, - NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment - NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq - NULL::VARCHAR, - CASE WHEN s_q3 THEN - COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0) - END, - CASE WHEN s_q3 THEN tb3.ac END, CASE WHEN s_q3 THEN tb3.as_v END, CASE WHEN s_q3 THEN tb3.arv END, - NULL::VARCHAR, - CASE WHEN s_q3 THEN - COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0) - END, - NULL::DATE, - CASE WHEN s_q3 THEN tb3.pa END, - NULL::VARCHAR, -- pay_comment - NULL::VARCHAR, -- pay_act - CASE WHEN s_q3 THEN tb3.bk END, -- booking (rollup) - CASE WHEN s_q3 THEN tb3.m1 END, CASE WHEN s_q3 THEN tb3.m2 END, CASE WHEN s_q3 THEN tb3.m3 END, - CASE WHEN s_q3 THEN COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) END, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)) - - COALESCE(tb3.bk,0) - END, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.sd3,0)+COALESCE(ta.sg3,0)+COALESCE(ta.sr3,0)+COALESCE(tb1.tq3,0)+COALESCE(tb2.tq3,0)+COALESCE(tb3.rev,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as_v,0)+COALESCE(tb3.arv,0)) - - (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)) - END, - CASE WHEN s_q3 THEN tb3.tq4 END, - CASE WHEN s_q3 THEN tb3.tda END, CASE WHEN s_q3 THEN tb3.tdp END, CASE WHEN s_q3 THEN tb3.terf END, - NULL::VARCHAR, -- transfer_next_comment (text, no rollup) - CASE WHEN s_q3 THEN tb3.te END, - CASE WHEN s_q3 THEN - COALESCE(tb3.tda,0)+COALESCE(tb3.tdp,0)+COALESCE(tb3.terf,0) - +COALESCE(tb3.te,0) - END, - NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, -- target_change/base_correction/comment - NULL::NUMERIC, NULL::NUMERIC, -- revision_inc/revision_seq - NULL::VARCHAR, - CASE WHEN s_q4 THEN - COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0) - END, - CASE WHEN s_q4 THEN tb4.ac END, CASE WHEN s_q4 THEN tb4.as_v END, CASE WHEN s_q4 THEN tb4.arv END, - NULL::VARCHAR, - CASE WHEN s_q4 THEN - COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0) - END, - NULL::DATE, - CASE WHEN s_q4 THEN tb4.pa END, - NULL::VARCHAR, -- pay_comment - NULL::VARCHAR, -- pay_act - CASE WHEN s_q4 THEN tb4.bk END, -- booking (rollup) - CASE WHEN s_q4 THEN tb4.m1 END, CASE WHEN s_q4 THEN tb4.m2 END, CASE WHEN s_q4 THEN tb4.m3 END, - CASE WHEN s_q4 THEN tb4.spod END, - CASE WHEN s_q4 THEN COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)) - - COALESCE(tb4.bk,0) - END, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0)+COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)) - - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)) - END, - CASE WHEN s_q4 THEN tb4.te END, - CASE WHEN s_q4 THEN tb4.te END, - CASE WHEN s_tot THEN COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0) - +COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0) - +COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0) - +COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0) END, - CASE WHEN s_tot THEN COALESCE(tb1.pa,0)+COALESCE(tb2.pa,0)+COALESCE(tb3.pa,0)+COALESCE(tb4.pa,0) END, - CASE WHEN s_tot THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.sd4,0)+COALESCE(ta.sg4,0)+COALESCE(ta.sr4,0) - +COALESCE(tb1.tq4,0)+COALESCE(tb2.tq4,0)+COALESCE(tb3.tq4,0)+COALESCE(tb4.rev,0) - +COALESCE(tb4.ac,0)+COALESCE(tb4.as_v,0)+COALESCE(tb4.arv,0)) - - (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)) - END, - - NULL::VARCHAR, -- internal_order - NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- contract_summary - NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, - NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- allocation - NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, -- collegial - NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, -- ckk - NULL::VARCHAR, NULL::VARCHAR, - NULL::VARCHAR, CASE WHEN s_cd THEN ta.bkc1 END, CASE WHEN s_cd THEN ta.bkc2 END, - CASE WHEN s_cd THEN ta.bkc3 END, CASE WHEN s_cd THEN ta.bkc4 END, - NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC, - NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q1 adj_rf/pho/prf - NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q2 - NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q3 - NULL::NUMERIC, NULL::NUMERIC, NULL::NUMERIC, -- q4 - - t.path AS _sort, - -t.id::BIGINT - FROM tw_f t - LEFT JOIN tw_agg ta ON ta.id = t.id - LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id - LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id - LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id - LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id - ) sub(row_type, depth, line_id, col_section_code, col_item_id, col_num_group_id, col_name, col_vsp_id, col_vsp_address, col_plan_q1, col_plan_q2, col_plan_q3, col_plan_q4, col_plan_year, col_plan_comment, col_seq_dfip_q1, col_seq_dfip_q2, col_seq_dfip_q3, col_seq_dfip_q4, col_seq_dfip_year, col_seq_dfip_just, col_seq_ssp_q1, col_seq_ssp_q2, col_seq_ssp_q3, col_seq_ssp_q4, col_seq_ssp_year, col_seq_ssp_just, col_appr_q1, col_appr_q2, col_appr_q3, col_appr_q4, col_appr_year, col_cd_counterparty, col_cd_reference, col_cd_date, col_cd_subject, col_cd_currency, col_cd_ceiling, col_cd_vat_rate, col_cd_deadline, col_cd_scheme, col_cd_act, col_cd_comment, col_book_q1, col_book_q2, col_book_q3, col_book_q4, col_book_next_q1, col_book_next_q2, col_book_next_q3, col_book_next_q4, col_q1_adj_current, col_q1_adj_ssp, col_q1_adj_reserve, col_q1_adj_comment, col_q1_corrected_plan, col_q1_pay_date, col_q1_pay_amount, col_q1_pay_comment, col_q1_pay_act, col_q1_booking, col_q1_actual_m1, col_q1_actual_m2, col_q1_actual_m3, col_q1_actual_quarter, col_q1_residual_after_booking, col_q1_residual_after_actual, col_q1_transfer_q2, col_q1_transfer_q2_delay_acts, col_q1_transfer_q2_delay_procurement, col_q1_transfer_q2_economy_rf, col_q1_transfer_next_comment, col_q1_transfer_q3, col_q1_transfer_q4, col_q1_transfer_far_comment, col_q1_transfer_econ, col_q1_total, col_q2_target_change, col_q2_base_correction, col_q2_base_correction_comment, col_q2_revision_inc, col_q2_revision_seq, col_q2_revision_comment, col_q2_new_plan, col_q2_adj_current, col_q2_adj_ssp, col_q2_adj_reserve, col_q2_adj_comment, col_q2_corrected_plan, col_q2_pay_date, col_q2_pay_amount, col_q2_pay_comment, col_q2_pay_act, col_q2_booking, col_q2_actual_m1, col_q2_actual_m2, col_q2_actual_m3, col_q2_actual_quarter, col_q2_residual_after_booking, col_q2_residual_after_actual, col_q2_transfer_q3, col_q2_transfer_q3_delay_acts, col_q2_transfer_q3_delay_procurement, col_q2_transfer_q3_economy_rf, col_q2_transfer_next_comment, col_q2_transfer_q4, col_q2_transfer_far_comment, col_q2_transfer_econ, col_q2_total, col_q3_target_change, col_q3_base_correction, col_q3_base_correction_comment, col_q3_revision_inc, col_q3_revision_seq, col_q3_revision_comment, col_q3_new_plan, col_q3_adj_current, col_q3_adj_ssp, col_q3_adj_reserve, col_q3_adj_comment, col_q3_corrected_plan, col_q3_pay_date, col_q3_pay_amount, col_q3_pay_comment, col_q3_pay_act, col_q3_booking, col_q3_actual_m1, col_q3_actual_m2, col_q3_actual_m3, col_q3_actual_quarter, col_q3_residual_after_booking, col_q3_residual_after_actual, col_q3_transfer_q4, col_q3_transfer_q4_delay_acts, col_q3_transfer_q4_delay_procurement, col_q3_transfer_q4_economy_rf, col_q3_transfer_next_comment, col_q3_transfer_econ, col_q3_total, col_q4_target_change, col_q4_base_correction, col_q4_base_correction_comment, col_q4_revision_inc, col_q4_revision_seq, col_q4_revision_comment, col_q4_new_plan, col_q4_adj_current, col_q4_adj_ssp, col_q4_adj_reserve, col_q4_adj_comment, col_q4_corrected_plan, col_q4_pay_date, col_q4_pay_amount, col_q4_pay_comment, col_q4_pay_act, col_q4_booking, col_q4_actual_m1, col_q4_actual_m2, col_q4_actual_m3, col_q4_actual_spod, col_q4_actual_quarter, col_q4_residual_after_booking, col_q4_residual_after_actual, col_q4_transfer_econ, col_q4_total, col_fact_year, col_pay_year, col_economy_year, col_internal_order, col_cs_total, col_cs_counterparty, col_cs_deadline, col_cs_comment, col_cs_future_y1, col_cs_future_y2, col_cs_other_ssp, col_al_contract_ref, col_al_purpose, col_al_order, col_al_property, col_ca_approved, col_ca_protocol, col_ca_note, col_ckk_ceiling, col_ckk_rf_sched, col_ckk_deadline, col_ckk_proc_plan, col_ckk_proc_meth, col_ckk_comment, col_cd_addenda, col_cd_exp_q1, col_cd_exp_q2, col_cd_exp_q3, col_cd_exp_q4, col_cd_rf_sched, col_cd_exchange_rate, col_cd_amount_foreign, col_q1_adj_rf, col_q1_pay_ho, col_q1_pay_rf, col_q2_adj_rf, col_q2_pay_ho, col_q2_pay_rf, col_q3_adj_rf, col_q3_pay_ho, col_q3_pay_rf, col_q4_adj_rf, col_q4_pay_ho, col_q4_pay_rf, _sort_path, _k) - JOIN sk ON sk.k = sub._k - ORDER BY sk.rnk; -END; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.v_form1_sheet_sections(p_form_id integer, p_sheet character varying, p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) - RETURNS TABLE(row_type character varying, depth integer, line_id integer, col_b_year integer, col_c_section character varying, col_d_item_id character varying, col_e_num_group character varying, col_f_name character varying, col_g_internal_order character varying, col_h_plan_q1 numeric, col_i_plan_q2 numeric, col_j_plan_q3 numeric, col_k_plan_q4 numeric, col_l_plan_year numeric, col_m_plan_comment character varying, col_n_cs_total numeric, col_o_cs_counterparty character varying, col_p_cs_deadline character varying, col_q_cs_comment character varying, col_r_cs_future_y1 numeric, col_s_cs_future_y2 numeric, col_t_cs_other_ssp numeric, col_v_al_order character varying, col_w_al_property character varying, col_y_seq_q1 numeric, col_z_seq_q2 numeric, col_aa_seq_q3 numeric, col_ab_seq_q4 numeric, col_ac_seq_year numeric, col_ad_seq_justification character varying, col_af_res_q1 numeric, col_ag_res_q2 numeric, col_ah_res_q3 numeric, col_ai_res_q4 numeric, col_aj_res_year numeric, col_ak_res_justification character varying, col_am_approved_q1 numeric, col_an_approved_q2 numeric, col_ao_approved_q3 numeric, col_ap_approved_q4 numeric, col_aq_approved_year numeric, col_as_ca_approved numeric, col_at_ca_protocol character varying, col_au_ca_note character varying, col_aw_ckk_ceiling numeric, col_ax_ckk_exp_q1 numeric, col_ay_ckk_exp_q2 numeric, col_az_ckk_exp_q3 numeric, col_ba_ckk_exp_q4 numeric, col_bb_ckk_rf_sched character varying, col_bc_ckk_deadline character varying, col_bd_ckk_proc_plan character varying, col_be_ckk_proc_meth character varying, col_bf_ckk_comment character varying, col_bh_cd_counterparty character varying, col_bi_cd_reference character varying, col_bj_cd_addenda character varying, col_bk_cd_subject character varying, col_bl_cd_currency character varying, col_bm_cd_ceiling numeric, col_bn_cd_exp_q1 numeric, col_bo_cd_exp_q2 numeric, col_bp_cd_exp_q3 numeric, col_bq_cd_exp_q4 numeric, col_br_cd_rf_sched character varying, col_bs_cd_vat character varying, col_bt_cd_rate numeric, col_bu_cd_amount_fx numeric, col_bv_cd_deadline character varying, col_bw_cd_scheme character varying, col_bx_cd_act character varying, col_by_cd_comment character varying, col_ca_q1_adj_current numeric, col_cb_q1_adj_ssp numeric, col_cc_q1_adj_rf numeric, col_cd_q1_adj_reserve numeric, col_ce_q1_adj_comment character varying, col_cf_q1_corrected_plan numeric, col_ch_q1_pay_date date, col_ci_q1_pay_amount numeric, col_cj_q1_pay_ho numeric, col_ck_q1_pay_rf numeric, col_cl_q1_pay_comment character varying, col_cm_q1_pay_act character varying, col_co_q1_booking numeric, col_cp_q1_actual_m1 numeric, col_cq_q1_actual_m2 numeric, col_cr_q1_actual_m3 numeric, col_cs_q1_actual_quarter numeric, col_ct_q1_rem_booking numeric, col_cu_q1_rem_actual numeric, col_cw_q1_trans_q2 numeric, col_cx_q1_trans_q3 numeric, col_cy_q1_trans_q4 numeric, col_cz_q1_economy numeric, col_da_q1_total numeric, col_dc_q2_rev_eco numeric, col_dd_q2_rev_item numeric, col_de_q2_rev_inc numeric, col_df_q2_rev_seq numeric, col_dg_q2_rev_comment character varying, col_dh_q2_new_plan numeric, col_dj_q2_adj_current numeric, col_dk_q2_adj_ssp numeric, col_dl_q2_adj_rf numeric, col_dm_q2_adj_reserve numeric, col_dn_q2_adj_comment character varying, col_do_q2_corrected_plan numeric, col_dq_q2_pay_date date, col_dr_q2_pay_amount numeric, col_ds_q2_pay_ho numeric, col_dt_q2_pay_rf numeric, col_du_q2_pay_comment character varying, col_dv_q2_pay_act character varying, col_dx_q2_booking numeric, col_dy_q2_actual_m1 numeric, col_dz_q2_actual_m2 numeric, col_ea_q2_actual_m3 numeric, col_eb_q2_actual_quarter numeric, col_ec_q2_rem_booking numeric, col_ed_q2_rem_actual numeric, col_ef_q2_trans_q3 numeric, col_eg_q2_trans_q4 numeric, col_eh_q2_economy numeric, col_ei_q2_total numeric, col_ek_q3_rev_eco numeric, col_el_q3_rev_item numeric, col_em_q3_rev_inc numeric, col_en_q3_rev_seq numeric, col_eo_q3_rev_comment character varying, col_ep_q3_new_plan numeric, col_er_q3_adj_current numeric, col_es_q3_adj_ssp numeric, col_et_q3_adj_rf numeric, col_eu_q3_adj_reserve numeric, col_ev_q3_adj_comment character varying, col_ew_q3_corrected_plan numeric, col_ey_q3_pay_date date, col_ez_q3_pay_amount numeric, col_fa_q3_pay_ho numeric, col_fb_q3_pay_rf numeric, col_fc_q3_pay_comment character varying, col_fd_q3_pay_act character varying, col_ff_q3_booking numeric, col_fg_q3_actual_m1 numeric, col_fh_q3_actual_m2 numeric, col_fi_q3_actual_m3 numeric, col_fj_q3_actual_quarter numeric, col_fk_q3_rem_booking numeric, col_fl_q3_rem_actual numeric, col_fn_q3_trans_q4 numeric, col_fo_q3_economy numeric, col_fp_q3_total numeric, col_fr_q4_rev_eco numeric, col_fs_q4_rev_item numeric, col_ft_q4_rev_inc numeric, col_fu_q4_rev_seq numeric, col_fv_q4_rev_comment character varying, col_fw_q4_new_plan numeric, col_fy_q4_adj_current numeric, col_fz_q4_adj_ssp numeric, col_ga_q4_adj_rf numeric, col_gb_q4_adj_reserve numeric, col_gc_q4_adj_comment character varying, col_gd_q4_corrected_plan numeric, col_gf_q4_pay_date date, col_gg_q4_pay_amount numeric, col_gh_q4_pay_ho numeric, col_gi_q4_pay_rf numeric, col_gj_q4_pay_comment character varying, col_gk_q4_pay_act character varying, col_gm_q4_booking numeric, col_gn_q4_actual_m1 numeric, col_go_q4_actual_m2 numeric, col_gp_q4_actual_m3 numeric, col_gq_q4_actual_quarter numeric, col_gr_q4_actual_spod numeric, col_gs_q4_rem_booking numeric, col_gt_q4_rem_actual numeric, col_gv_q4_economy numeric, col_gw_q4_total numeric, col_gz_fact_year numeric, col_hb_pay_year numeric, _sort_path integer[], _sort_rank bigint) - LANGUAGE plpgsql - STABLE - SET jit TO 'off' - SET search_path TO 'v3', 'pg_catalog' -AS $function$ -#variable_conflict use_column -DECLARE - v_year INT; - s_plan BOOL; s_cs BOOL; s_al BOOL; s_seq BOOL; s_res BOOL; - s_appr BOOL; s_ca BOOL; s_ckk BOOL; s_cd BOOL; - s_q1 BOOL; s_q2 BOOL; s_q3 BOOL; s_q4 BOOL; s_tot BOOL; - s_any_q BOOL; - s_need_ap BOOL; - s_need_bk BOOL; - v_focus_nodes INT[]; -- AURORA-1850: узлы фокуса (путь статей строк фокуса ∩ tw); NULL = весь лист - v_focus_eids INT[]; -- AURORA-1850: объединение desc_ids узлов фокуса -BEGIN - SELECT bf.year INTO v_year FROM budget_form bf WHERE bf.id = p_form_id; - - s_plan := p_sections IS NULL OR 'plan' = ANY(p_sections); - s_cs := p_sections IS NULL OR 'contract_summary' = ANY(p_sections); - s_al := p_sections IS NULL OR 'allocation' = ANY(p_sections); - s_seq := p_sections IS NULL OR 'sequestration' = ANY(p_sections); - s_res := p_sections IS NULL OR 'reserve' = ANY(p_sections); - s_appr := p_sections IS NULL OR 'approved' = ANY(p_sections); - s_ca := p_sections IS NULL OR 'collegial' = ANY(p_sections); - s_ckk := p_sections IS NULL OR 'ckk' = ANY(p_sections); - s_cd := p_sections IS NULL OR 'contract_detail' = ANY(p_sections); - s_q1 := p_sections IS NULL OR 'q1' = ANY(p_sections); - s_q2 := p_sections IS NULL OR 'q2' = ANY(p_sections); - s_q3 := p_sections IS NULL OR 'q3' = ANY(p_sections); - s_q4 := p_sections IS NULL OR 'q4' = ANY(p_sections); - s_tot := p_sections IS NULL OR 'totals' = ANY(p_sections); - s_any_q := s_q1 OR s_q2 OR s_q3 OR s_q4 OR s_tot; - s_need_ap := s_plan OR s_appr OR s_q1 OR s_q2 OR s_q3 OR s_q4; - s_need_bk := s_q1 OR s_q2 OR s_q3 OR s_q4; - - -- Фокус (D1): NULL = весь лист, '{}' = пустой результат. COALESCE обязателен: - -- пустой фокус не должен превратиться в NULL и провалиться в полную сборку. - -- Узлы фокуса берутся из budget_line БЕЗ фильтра direction (tw тоже без него). - IF p_focus_lines IS NOT NULL THEN - WITH fp AS ( - SELECT v3._expense_item_path_set( - (SELECT array_agg(DISTINCT bl.expense_item_id) - FROM v3.budget_line bl - WHERE bl.id = ANY(p_focus_lines))) AS ids - ), - fn AS ( - SELECT t.id, t.desc_ids - FROM v3.mv_expense_item_tree t - JOIN v3.expense_item_form_type eft ON eft.expense_item_id = t.id - JOIN v3.budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code - WHERE t.sheet = p_sheet - AND t.id = ANY(COALESCE((SELECT fp.ids FROM fp), '{}'::int[])) - ) - SELECT COALESCE((SELECT array_agg(fn.id) FROM fn), '{}'::int[]), - COALESCE((SELECT array_agg(DISTINCT d) FROM fn, unnest(fn.desc_ids) AS d), '{}'::int[]) - INTO v_focus_nodes, v_focus_eids; - END IF; - - RETURN QUERY - WITH - tw AS ( - SELECT t.id, t.section_code, t.item_id, t.num_group_id, t.name, - t.depth, t.path, t.parent_id, t.parent_item_id, t.desc_ids, - p.parent_item_id AS grandparent_item_id - FROM mv_expense_item_tree t - LEFT JOIN mv_expense_item_tree p ON p.id = t.parent_id - JOIN expense_item_form_type eft ON eft.expense_item_id = t.id - JOIN budget_form bf ON bf.id = p_form_id AND bf.form_type_code = eft.form_type_code - WHERE t.sheet = p_sheet - ), - - page AS ( - SELECT bl.id AS lid, bl.expense_item_id AS eid, bl.internal_order AS io, - bl.name AS bname - FROM budget_line bl - JOIN expense_item ei ON ei.id = bl.expense_item_id - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet - AND (p_direction IS NULL OR bl.direction IS NULL OR bl.direction = p_direction) - ), - - tw_f AS ( - SELECT * FROM tw WHERE p_focus_lines IS NULL OR tw.id = ANY(v_focus_nodes) - ), - page_f AS ( - SELECT * FROM page WHERE p_focus_lines IS NULL OR page.lid = ANY(p_focus_lines) - ), - -- Скелет листа (D2): ключи всех узлов tw и всех строк page JOIN tw (page уже с фильтром direction), - -- без jsonb и сумм. Ранг одинаков в обоих режимах; tie-break D6: узел раньше строки. - sk AS ( - SELECT n.k, - ROW_NUMBER() OVER (ORDER BY n._sort, n.lid NULLS FIRST) AS rnk - FROM ( - SELECT -t0.id::BIGINT AS k, NULL::INT AS lid, t0.path AS _sort FROM tw t0 - UNION ALL - SELECT pg0.lid::BIGINT, pg0.lid::INT, t1.path || ARRAY[pg0.lid::INT] - FROM page pg0 JOIN tw t1 ON t1.id = pg0.eid - ) n - ), - - jp AS (SELECT p.* FROM plan p JOIN page_f pg ON p.line_id = pg.lid WHERE s_plan), - jcs AS (SELECT cs.* FROM contract_summary cs JOIN page_f pg ON cs.line_id = pg.lid WHERE s_cs), - jal AS (SELECT al.* FROM allocation al JOIN page_f pg ON al.line_id = pg.lid WHERE s_al), - jsd AS (SELECT sd.* FROM sequestration sd JOIN page_f pg ON sd.line_id = pg.lid WHERE s_seq AND sd.actor='DFIP'), - jr AS (SELECT r.* FROM reserve r JOIN page_f pg ON r.line_id = pg.lid WHERE s_res), - jca AS (SELECT ca.* FROM collegial_approval ca JOIN page_f pg ON ca.line_id = pg.lid WHERE s_ca), - jck AS (SELECT ck.* FROM ckk ck JOIN page_f pg ON ck.line_id = pg.lid WHERE s_ckk), - jcd AS (SELECT cd.* FROM contract_detail cd JOIN page_f pg ON cd.line_id = pg.lid WHERE s_cd), - jq1 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE s_q1 AND blq.quarter = 1), - jq2 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE s_q2 AND blq.quarter = 2), - jq3 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE s_q3 AND blq.quarter = 3), - jq4 AS (SELECT blq.* FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid WHERE (s_q4 OR s_tot) AND blq.quarter = 4), - jtot AS ( - SELECT blq.line_id AS tlid, - SUM(CASE WHEN blq.quarter=1 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq1, - SUM(CASE WHEN blq.quarter=2 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq2, - SUM(CASE WHEN blq.quarter=3 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS tot_aq3, - SUM(CASE WHEN blq.quarter=4 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0)+COALESCE(blq.actual_spod,0) END) AS tot_aq4, - SUM(CASE WHEN blq.quarter=1 THEN blq.payment_amount END) AS tot_pa1, - SUM(CASE WHEN blq.quarter=2 THEN blq.payment_amount END) AS tot_pa2, - SUM(CASE WHEN blq.quarter=3 THEN blq.payment_amount END) AS tot_pa3, - SUM(CASE WHEN blq.quarter=4 THEN blq.payment_amount END) AS tot_pa4 - FROM budget_line_quarter blq JOIN page_f pg ON blq.line_id = pg.lid - WHERE s_tot - GROUP BY blq.line_id - ), - - input_base AS ( - SELECT - pg.lid, pg.eid, pg.io, pg.bname, - CASE - WHEN t.depth < 3 THEN t.item_id - WHEN t.depth = 3 THEN t.parent_item_id - WHEN t.depth = 4 THEN t.grandparent_item_id - END AS sc, - t.item_id AS ic, - t.num_group_id AS ng, t.name AS ename, - COALESCE(p.plan_q1,0) AS pq1, COALESCE(p.plan_q2,0) AS pq2, - COALESCE(p.plan_q3,0) AS pq3, COALESCE(p.plan_q4,0) AS pq4, - p.comment AS pcmt, - COALESCE(sd.adj_q1,0) AS sq1, COALESCE(sd.adj_q2,0) AS sq2, - COALESCE(sd.adj_q3,0) AS sq3, COALESCE(sd.adj_q4,0) AS sq4, - sd.justification AS sjust, - COALESCE(r.amount_q1,0) AS rq1, COALESCE(r.amount_q2,0) AS rq2, - COALESCE(r.amount_q3,0) AS rq3, COALESCE(r.amount_q4,0) AS rq4, - r.justification AS rjust, - cs.*, al.internal_order AS al_io, al.property_object AS al_po, - ca.approved_amount AS ca_amt, ca.protocol_reference AS ca_prot, ca.note AS ca_note, - ck.ceiling_amount AS ckk_ceil, - COALESCE(ck.expenses_q1,0) AS ckk1, COALESCE(ck.expenses_q2,0) AS ckk2, - COALESCE(ck.expenses_q3,0) AS ckk3, COALESCE(ck.expenses_q4,0) AS ckk4, - ck.rf_schedule AS ckk_rf, ck.delivery_deadline AS ckk_dl, - ck.procurement_plan AS ckk_pp, ck.procurement_method AS ckk_pm, ck.comment AS ckk_cmt, - cd.counterparty AS cd_cp, cd.reference AS cd_ref, cd.addenda AS cd_add, - cd.subject AS cd_subj, cd.currency AS cd_cur, cd.ceiling_amount AS cd_ceil, - COALESCE(cd.expenses_q1,0) AS cdq1, COALESCE(cd.expenses_q2,0) AS cdq2, - COALESCE(cd.expenses_q3,0) AS cdq3, COALESCE(cd.expenses_q4,0) AS cdq4, - cd.rf_schedule AS cd_rf, cd.vat_rate AS cd_vat, cd.exchange_rate AS cd_rate, - cd.amount_foreign AS cd_fx, cd.deadline AS cd_dl, cd.payment_scheme AS cd_sch, - cd.act AS cd_act, cd.comment AS cd_cmt2, - q1.adj_current AS q1_ac, q1.adj_ssp AS q1_as, q1.adj_rf AS q1_ar, q1.adj_reserve AS q1_arv, - q1.adj_comment AS q1_acmt, q1.payment_date AS q1_pd, q1.payment_amount AS q1_pa, - q1.payment_amount_ho AS q1_pho, q1.payment_amount_rf AS q1_prf, - q1.payment_comment AS q1_pcmt, q1.payment_act AS q1_pact, - q1.actual_m1 AS q1_m1, q1.actual_m2 AS q1_m2, q1.actual_m3 AS q1_m3, - q1.transfer_to_q2 AS q1_tq2, q1.transfer_to_q3 AS q1_tq3, q1.transfer_to_q4 AS q1_tq4, - q2.plan_revision_eco_change AS q2_reco, q2.plan_revision_item_adj AS q2_ritm, - q2.plan_revision_increase AS q2_rinc, q2.plan_revision_sequester AS q2_rseq, - q2.plan_revision_comment AS q2_rcmt, - q2.adj_current AS q2_ac, q2.adj_ssp AS q2_as, q2.adj_rf AS q2_ar, q2.adj_reserve AS q2_arv, - q2.adj_comment AS q2_acmt, q2.payment_date AS q2_pd, q2.payment_amount AS q2_pa, - q2.payment_amount_ho AS q2_pho, q2.payment_amount_rf AS q2_prf, - q2.payment_comment AS q2_pcmt, q2.payment_act AS q2_pact, - q2.actual_m1 AS q2_m1, q2.actual_m2 AS q2_m2, q2.actual_m3 AS q2_m3, - q2.transfer_to_q3 AS q2_tq3, q2.transfer_to_q4 AS q2_tq4, - q3.plan_revision_eco_change AS q3_reco, q3.plan_revision_item_adj AS q3_ritm, - q3.plan_revision_increase AS q3_rinc, q3.plan_revision_sequester AS q3_rseq, - q3.plan_revision_comment AS q3_rcmt, - q3.adj_current AS q3_ac, q3.adj_ssp AS q3_as, q3.adj_rf AS q3_ar, q3.adj_reserve AS q3_arv, - q3.adj_comment AS q3_acmt, q3.payment_date AS q3_pd, q3.payment_amount AS q3_pa, - q3.payment_amount_ho AS q3_pho, q3.payment_amount_rf AS q3_prf, - q3.payment_comment AS q3_pcmt, q3.payment_act AS q3_pact, - q3.actual_m1 AS q3_m1, q3.actual_m2 AS q3_m2, q3.actual_m3 AS q3_m3, - q3.transfer_to_q4 AS q3_tq4, - q4.plan_revision_eco_change AS q4_reco, q4.plan_revision_item_adj AS q4_ritm, - q4.plan_revision_increase AS q4_rinc, q4.plan_revision_sequester AS q4_rseq, - q4.plan_revision_comment AS q4_rcmt, - q4.adj_current AS q4_ac, q4.adj_ssp AS q4_as, q4.adj_rf AS q4_ar, q4.adj_reserve AS q4_arv, - q4.adj_comment AS q4_acmt, q4.payment_date AS q4_pd, q4.payment_amount AS q4_pa, - q4.payment_amount_ho AS q4_pho, q4.payment_amount_rf AS q4_prf, - q4.payment_comment AS q4_pcmt, q4.payment_act AS q4_pact, - q4.actual_m1 AS q4_m1, q4.actual_m2 AS q4_m2, q4.actual_m3 AS q4_m3, - q4.actual_spod AS q4_spod, - tot.tot_aq1, tot.tot_aq2, tot.tot_aq3, tot.tot_aq4, - tot.tot_pa1, tot.tot_pa2, tot.tot_pa3, tot.tot_pa4, - CASE WHEN COALESCE(cd.expenses_q1,0)>0 THEN cd.expenses_q1 ELSE ck.expenses_q1 END AS bk1, - CASE WHEN COALESCE(cd.expenses_q2,0)>0 THEN cd.expenses_q2 ELSE ck.expenses_q2 END AS bk2, - CASE WHEN COALESCE(cd.expenses_q3,0)>0 THEN cd.expenses_q3 ELSE ck.expenses_q3 END AS bk3, - CASE WHEN COALESCE(cd.expenses_q4,0)>0 THEN cd.expenses_q4 ELSE ck.expenses_q4 END AS bk4, - COALESCE(p.plan_q1,0)+COALESCE(sd.adj_q1,0)+COALESCE(r.amount_q1,0) AS ap1, - COALESCE(p.plan_q2,0)+COALESCE(sd.adj_q2,0)+COALESCE(r.amount_q2,0) AS ap2, - COALESCE(p.plan_q3,0)+COALESCE(sd.adj_q3,0)+COALESCE(r.amount_q3,0) AS ap3, - COALESCE(p.plan_q4,0)+COALESCE(sd.adj_q4,0)+COALESCE(r.amount_q4,0) AS ap4, - t.path AS tree_path - FROM page_f pg - JOIN tw t ON t.id = pg.eid - LEFT JOIN jp p ON p.line_id = pg.lid - LEFT JOIN jcs cs ON cs.line_id = pg.lid - LEFT JOIN jal al ON al.line_id = pg.lid - LEFT JOIN jsd sd ON sd.line_id = pg.lid - LEFT JOIN jr r ON r.line_id = pg.lid - LEFT JOIN jca ca ON ca.line_id = pg.lid - LEFT JOIN jck ck ON ck.line_id = pg.lid - LEFT JOIN jcd cd ON cd.line_id = pg.lid - LEFT JOIN jq1 q1 ON q1.line_id = pg.lid - LEFT JOIN jq2 q2 ON q2.line_id = pg.lid - LEFT JOIN jq3 q3 ON q3.line_id = pg.lid - LEFT JOIN jq4 q4 ON q4.line_id = pg.lid - LEFT JOIN jtot tot ON tot.tlid = pg.lid - ), - enriched AS ( - SELECT b.*, - b.ap1 + COALESCE(b.q1_ac,0)+COALESCE(b.q1_as,0)+COALESCE(b.q1_ar,0)+COALESCE(b.q1_arv,0) AS cp1, - COALESCE(b.q1_m1,0)+COALESCE(b.q1_m2,0)+COALESCE(b.q1_m3,0) AS aq1, - b.ap2 + COALESCE(b.q1_tq2,0) + COALESCE(b.q2_reco,0)+COALESCE(b.q2_ritm,0)+COALESCE(b.q2_rinc,0)+COALESCE(b.q2_rseq,0) AS np2, - COALESCE(b.q2_m1,0)+COALESCE(b.q2_m2,0)+COALESCE(b.q2_m3,0) AS aq2, - b.ap3 + COALESCE(b.q1_tq3,0)+COALESCE(b.q2_tq3,0) + COALESCE(b.q3_reco,0)+COALESCE(b.q3_ritm,0)+COALESCE(b.q3_rinc,0)+COALESCE(b.q3_rseq,0) AS np3, - COALESCE(b.q3_m1,0)+COALESCE(b.q3_m2,0)+COALESCE(b.q3_m3,0) AS aq3, - b.ap4 + COALESCE(b.q1_tq4,0)+COALESCE(b.q2_tq4,0)+COALESCE(b.q3_tq4,0) + COALESCE(b.q4_reco,0)+COALESCE(b.q4_ritm,0)+COALESCE(b.q4_rinc,0)+COALESCE(b.q4_rseq,0) AS np4, - COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0) AS aq4_no_spod, - COALESCE(b.q4_m1,0)+COALESCE(b.q4_m2,0)+COALESCE(b.q4_m3,0)+COALESCE(b.q4_spod,0) AS aq4 - FROM input_base b - ), - final_input AS ( - SELECT e.*, - e.np2 + COALESCE(e.q2_ac,0)+COALESCE(e.q2_as,0)+COALESCE(e.q2_ar,0)+COALESCE(e.q2_arv,0) AS cp2, - e.np3 + COALESCE(e.q3_ac,0)+COALESCE(e.q3_as,0)+COALESCE(e.q3_ar,0)+COALESCE(e.q3_arv,0) AS cp3, - e.np4 + COALESCE(e.q4_ac,0)+COALESCE(e.q4_as,0)+COALESCE(e.q4_ar,0)+COALESCE(e.q4_arv,0) AS cp4 - FROM enriched e - ), - - agg AS ( - SELECT bl.expense_item_id AS eid, - SUM(p.plan_q1) AS sp1, SUM(p.plan_q2) AS sp2, SUM(p.plan_q3) AS sp3, SUM(p.plan_q4) AS sp4, - SUM(sd.adj_q1) AS ss1, SUM(sd.adj_q2) AS ss2, SUM(sd.adj_q3) AS ss3, SUM(sd.adj_q4) AS ss4, - SUM(r.amount_q1) AS sr1, SUM(r.amount_q2) AS sr2, SUM(r.amount_q3) AS sr3, SUM(r.amount_q4) AS sr4, - SUM(ca.approved_amount) AS sca, - SUM(ck.ceiling_amount) AS sckc, - SUM(ck.expenses_q1) AS sck1, SUM(ck.expenses_q2) AS sck2, SUM(ck.expenses_q3) AS sck3, SUM(ck.expenses_q4) AS sck4, - SUM(cd.ceiling_amount) AS scdc, - SUM(cd.expenses_q1) AS scd1, SUM(cd.expenses_q2) AS scd2, SUM(cd.expenses_q3) AS scd3, SUM(cd.expenses_q4) AS scd4, - SUM(cs.total_amount) AS scst, SUM(cs.future_payments_y1) AS sfy1, SUM(cs.future_payments_y2) AS sfy2, - SUM(cs.other_ssp_amount) AS sossp - FROM budget_line bl - JOIN expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN plan p ON p.line_id = bl.id AND s_need_ap - LEFT JOIN contract_summary cs ON cs.line_id = bl.id AND s_cs - LEFT JOIN sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP' AND s_need_ap - LEFT JOIN reserve r ON r.line_id = bl.id AND s_need_ap - LEFT JOIN collegial_approval ca ON ca.line_id = bl.id AND s_ca - LEFT JOIN ckk ck ON ck.line_id = bl.id AND (s_ckk OR s_need_bk) - LEFT JOIN contract_detail cd ON cd.line_id = bl.id AND (s_cd OR s_need_bk) - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - AND (s_need_ap OR s_cs OR s_ca OR s_ckk OR s_cd OR s_need_bk) - GROUP BY bl.expense_item_id - ), - aq1 AS ( - SELECT bl.expense_item_id AS eid, - SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, - SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, - SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, - SUM(blq.transfer_to_q2) AS tq2, SUM(blq.transfer_to_q3) AS tq3, SUM(blq.transfer_to_q4) AS tq4 - FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 1 - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q1 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id - ), - aq2 AS ( - SELECT bl.expense_item_id AS eid, - SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm, - SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq, - SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, - SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, - SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, - SUM(blq.transfer_to_q3) AS tq3, SUM(blq.transfer_to_q4) AS tq4 - FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 2 - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q2 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id - ), - aq3 AS ( - SELECT bl.expense_item_id AS eid, - SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm, - SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq, - SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, - SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, - SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, - SUM(blq.transfer_to_q4) AS tq4 - FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 3 - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_q3 AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id - ), - aq4 AS ( - SELECT bl.expense_item_id AS eid, - SUM(blq.plan_revision_eco_change) AS reco, SUM(blq.plan_revision_item_adj) AS ritm, - SUM(blq.plan_revision_increase) AS rinc, SUM(blq.plan_revision_sequester) AS rseq, - SUM(blq.adj_current) AS ac, SUM(blq.adj_ssp) AS as2, SUM(blq.adj_rf) AS ar, SUM(blq.adj_reserve) AS arv, - SUM(blq.payment_amount) AS pa, SUM(blq.payment_amount_ho) AS pho, SUM(blq.payment_amount_rf) AS prf, - SUM(blq.actual_m1) AS m1, SUM(blq.actual_m2) AS m2, SUM(blq.actual_m3) AS m3, - SUM(blq.actual_spod) AS spod - FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id AND blq.quarter = 4 - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND (s_q4 OR s_tot) AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id - ), - atot AS ( - SELECT bl.expense_item_id AS eid, - SUM(CASE WHEN blq.quarter=1 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq1, - SUM(CASE WHEN blq.quarter=2 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq2, - SUM(CASE WHEN blq.quarter=3 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0) END) AS fq3, - SUM(CASE WHEN blq.quarter=4 THEN COALESCE(blq.actual_m1,0)+COALESCE(blq.actual_m2,0)+COALESCE(blq.actual_m3,0)+COALESCE(blq.actual_spod,0) END) AS fq4, - SUM(blq.payment_amount) AS pay - FROM budget_line bl JOIN expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN budget_line_quarter blq ON blq.line_id = bl.id - WHERE bl.budget_form_id = p_form_id AND ei.sheet = p_sheet AND s_tot AND (p_direction is null OR bl.direction is null or bl.direction = p_direction) - AND (p_focus_lines IS NULL OR bl.expense_item_id = ANY(v_focus_eids)) - GROUP BY bl.expense_item_id - ), - tw_agg AS ( - SELECT tw.id, - SUM(a.sp1) AS sp1, SUM(a.sp2) AS sp2, SUM(a.sp3) AS sp3, SUM(a.sp4) AS sp4, - SUM(a.ss1) AS ss1, SUM(a.ss2) AS ss2, SUM(a.ss3) AS ss3, SUM(a.ss4) AS ss4, - SUM(a.sr1) AS sr1, SUM(a.sr2) AS sr2, SUM(a.sr3) AS sr3, SUM(a.sr4) AS sr4, - SUM(a.sca) AS sca, - SUM(a.sckc) AS sckc, SUM(a.sck1) AS sck1, SUM(a.sck2) AS sck2, SUM(a.sck3) AS sck3, SUM(a.sck4) AS sck4, - SUM(a.scdc) AS scdc, SUM(a.scd1) AS scd1, SUM(a.scd2) AS scd2, SUM(a.scd3) AS scd3, SUM(a.scd4) AS scd4, - SUM(a.scst) AS scst, SUM(a.sfy1) AS sfy1, SUM(a.sfy2) AS sfy2, SUM(a.sossp) AS sossp, - SUM(CASE WHEN COALESCE(a.scd1,0)>0 THEN a.scd1 ELSE a.sck1 END) AS bk1, - SUM(CASE WHEN COALESCE(a.scd2,0)>0 THEN a.scd2 ELSE a.sck2 END) AS bk2, - SUM(CASE WHEN COALESCE(a.scd3,0)>0 THEN a.scd3 ELSE a.sck3 END) AS bk3, - SUM(CASE WHEN COALESCE(a.scd4,0)>0 THEN a.scd4 ELSE a.sck4 END) AS bk4 - FROM tw_f tw LEFT JOIN agg a ON a.eid = ANY(tw.desc_ids) - GROUP BY tw.id - ), - tw_aq1 AS ( - SELECT tw.id, SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.tq2) AS tq2, SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4 - FROM tw_f tw LEFT JOIN aq1 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id - ), - tw_aq2 AS ( - SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq, - SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.tq3) AS tq3, SUM(b.tq4) AS tq4 - FROM tw_f tw LEFT JOIN aq2 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id - ), - tw_aq3 AS ( - SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq, - SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.tq4) AS tq4 - FROM tw_f tw LEFT JOIN aq3 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id - ), - tw_aq4 AS ( - SELECT tw.id, SUM(b.reco) AS reco, SUM(b.ritm) AS ritm, SUM(b.rinc) AS rinc, SUM(b.rseq) AS rseq, - SUM(b.ac) AS ac, SUM(b.as2) AS as2, SUM(b.ar) AS ar, SUM(b.arv) AS arv, - SUM(b.pa) AS pa, SUM(b.pho) AS pho, SUM(b.prf) AS prf, - SUM(b.m1) AS m1, SUM(b.m2) AS m2, SUM(b.m3) AS m3, - SUM(b.spod) AS spod - FROM tw_f tw LEFT JOIN aq4 b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id - ), - tw_atot AS ( - SELECT tw.id, SUM(b.fq1) AS fq1, SUM(b.fq2) AS fq2, SUM(b.fq3) AS fq3, SUM(b.fq4) AS fq4, - SUM(b.pay) AS pay - FROM tw_f tw LEFT JOIN atot b ON b.eid = ANY(tw.desc_ids) GROUP BY tw.id - ) - - SELECT sub.row_type, sub.depth, sub.line_id, sub.col_b_year, sub.col_c_section, sub.col_d_item_id, sub.col_e_num_group, sub.col_f_name, sub.col_g_internal_order, sub.col_h_plan_q1, sub.col_i_plan_q2, sub.col_j_plan_q3, sub.col_k_plan_q4, sub.col_l_plan_year, sub.col_m_plan_comment, sub.col_n_cs_total, sub.col_o_cs_counterparty, sub.col_p_cs_deadline, sub.col_q_cs_comment, sub.col_r_cs_future_y1, sub.col_s_cs_future_y2, sub.col_t_cs_other_ssp, sub.col_v_al_order, sub.col_w_al_property, sub.col_y_seq_q1, sub.col_z_seq_q2, sub.col_aa_seq_q3, sub.col_ab_seq_q4, sub.col_ac_seq_year, sub.col_ad_seq_justification, sub.col_af_res_q1, sub.col_ag_res_q2, sub.col_ah_res_q3, sub.col_ai_res_q4, sub.col_aj_res_year, sub.col_ak_res_justification, sub.col_am_approved_q1, sub.col_an_approved_q2, sub.col_ao_approved_q3, sub.col_ap_approved_q4, sub.col_aq_approved_year, sub.col_as_ca_approved, sub.col_at_ca_protocol, sub.col_au_ca_note, sub.col_aw_ckk_ceiling, sub.col_ax_ckk_exp_q1, sub.col_ay_ckk_exp_q2, sub.col_az_ckk_exp_q3, sub.col_ba_ckk_exp_q4, sub.col_bb_ckk_rf_sched, sub.col_bc_ckk_deadline, sub.col_bd_ckk_proc_plan, sub.col_be_ckk_proc_meth, sub.col_bf_ckk_comment, sub.col_bh_cd_counterparty, sub.col_bi_cd_reference, sub.col_bj_cd_addenda, sub.col_bk_cd_subject, sub.col_bl_cd_currency, sub.col_bm_cd_ceiling, sub.col_bn_cd_exp_q1, sub.col_bo_cd_exp_q2, sub.col_bp_cd_exp_q3, sub.col_bq_cd_exp_q4, sub.col_br_cd_rf_sched, sub.col_bs_cd_vat, sub.col_bt_cd_rate, sub.col_bu_cd_amount_fx, sub.col_bv_cd_deadline, sub.col_bw_cd_scheme, sub.col_bx_cd_act, sub.col_by_cd_comment, sub.col_ca_q1_adj_current, sub.col_cb_q1_adj_ssp, sub.col_cc_q1_adj_rf, sub.col_cd_q1_adj_reserve, sub.col_ce_q1_adj_comment, sub.col_cf_q1_corrected_plan, sub.col_ch_q1_pay_date, sub.col_ci_q1_pay_amount, sub.col_cj_q1_pay_ho, sub.col_ck_q1_pay_rf, sub.col_cl_q1_pay_comment, sub.col_cm_q1_pay_act, sub.col_co_q1_booking, sub.col_cp_q1_actual_m1, sub.col_cq_q1_actual_m2, sub.col_cr_q1_actual_m3, sub.col_cs_q1_actual_quarter, sub.col_ct_q1_rem_booking, sub.col_cu_q1_rem_actual, sub.col_cw_q1_trans_q2, sub.col_cx_q1_trans_q3, sub.col_cy_q1_trans_q4, sub.col_cz_q1_economy, sub.col_da_q1_total, sub.col_dc_q2_rev_eco, sub.col_dd_q2_rev_item, sub.col_de_q2_rev_inc, sub.col_df_q2_rev_seq, sub.col_dg_q2_rev_comment, sub.col_dh_q2_new_plan, sub.col_dj_q2_adj_current, sub.col_dk_q2_adj_ssp, sub.col_dl_q2_adj_rf, sub.col_dm_q2_adj_reserve, sub.col_dn_q2_adj_comment, sub.col_do_q2_corrected_plan, sub.col_dq_q2_pay_date, sub.col_dr_q2_pay_amount, sub.col_ds_q2_pay_ho, sub.col_dt_q2_pay_rf, sub.col_du_q2_pay_comment, sub.col_dv_q2_pay_act, sub.col_dx_q2_booking, sub.col_dy_q2_actual_m1, sub.col_dz_q2_actual_m2, sub.col_ea_q2_actual_m3, sub.col_eb_q2_actual_quarter, sub.col_ec_q2_rem_booking, sub.col_ed_q2_rem_actual, sub.col_ef_q2_trans_q3, sub.col_eg_q2_trans_q4, sub.col_eh_q2_economy, sub.col_ei_q2_total, sub.col_ek_q3_rev_eco, sub.col_el_q3_rev_item, sub.col_em_q3_rev_inc, sub.col_en_q3_rev_seq, sub.col_eo_q3_rev_comment, sub.col_ep_q3_new_plan, sub.col_er_q3_adj_current, sub.col_es_q3_adj_ssp, sub.col_et_q3_adj_rf, sub.col_eu_q3_adj_reserve, sub.col_ev_q3_adj_comment, sub.col_ew_q3_corrected_plan, sub.col_ey_q3_pay_date, sub.col_ez_q3_pay_amount, sub.col_fa_q3_pay_ho, sub.col_fb_q3_pay_rf, sub.col_fc_q3_pay_comment, sub.col_fd_q3_pay_act, sub.col_ff_q3_booking, sub.col_fg_q3_actual_m1, sub.col_fh_q3_actual_m2, sub.col_fi_q3_actual_m3, sub.col_fj_q3_actual_quarter, sub.col_fk_q3_rem_booking, sub.col_fl_q3_rem_actual, sub.col_fn_q3_trans_q4, sub.col_fo_q3_economy, sub.col_fp_q3_total, sub.col_fr_q4_rev_eco, sub.col_fs_q4_rev_item, sub.col_ft_q4_rev_inc, sub.col_fu_q4_rev_seq, sub.col_fv_q4_rev_comment, sub.col_fw_q4_new_plan, sub.col_fy_q4_adj_current, sub.col_fz_q4_adj_ssp, sub.col_ga_q4_adj_rf, sub.col_gb_q4_adj_reserve, sub.col_gc_q4_adj_comment, sub.col_gd_q4_corrected_plan, sub.col_gf_q4_pay_date, sub.col_gg_q4_pay_amount, sub.col_gh_q4_pay_ho, sub.col_gi_q4_pay_rf, sub.col_gj_q4_pay_comment, sub.col_gk_q4_pay_act, sub.col_gm_q4_booking, sub.col_gn_q4_actual_m1, sub.col_go_q4_actual_m2, sub.col_gp_q4_actual_m3, sub.col_gq_q4_actual_quarter, sub.col_gr_q4_actual_spod, sub.col_gs_q4_rem_booking, sub.col_gt_q4_rem_actual, sub.col_gv_q4_economy, sub.col_gw_q4_total, sub.col_gz_fact_year, sub.col_hb_pay_year, sub._sort_path, sk.rnk - FROM ( - SELECT - 'INPUT'::VARCHAR, array_length(f.tree_path, 1)::INT, f.lid, - v_year, f.sc, f.ic, f.ng, COALESCE(f.bname, f.ename), f.io, - CASE WHEN s_plan THEN f.pq1 END, CASE WHEN s_plan THEN f.pq2 END, - CASE WHEN s_plan THEN f.pq3 END, CASE WHEN s_plan THEN f.pq4 END, - CASE WHEN s_plan THEN f.pq1+f.pq2+f.pq3+f.pq4 END, CASE WHEN s_plan THEN f.pcmt END, - CASE WHEN s_cs THEN f.total_amount END, CASE WHEN s_cs THEN f.counterparty END, - CASE WHEN s_cs THEN f.deadline END, CASE WHEN s_cs THEN f.comment END, - CASE WHEN s_cs THEN f.future_payments_y1 END, CASE WHEN s_cs THEN f.future_payments_y2 END, - CASE WHEN s_cs THEN f.other_ssp_amount END, - CASE WHEN s_al THEN f.al_io END, CASE WHEN s_al THEN f.al_po END, - CASE WHEN s_seq THEN f.sq1 END, CASE WHEN s_seq THEN f.sq2 END, - CASE WHEN s_seq THEN f.sq3 END, CASE WHEN s_seq THEN f.sq4 END, - CASE WHEN s_seq THEN f.sq1+f.sq2+f.sq3+f.sq4 END, CASE WHEN s_seq THEN f.sjust END, - CASE WHEN s_res THEN f.rq1 END, CASE WHEN s_res THEN f.rq2 END, - CASE WHEN s_res THEN f.rq3 END, CASE WHEN s_res THEN f.rq4 END, - CASE WHEN s_res THEN f.rq1+f.rq2+f.rq3+f.rq4 END, CASE WHEN s_res THEN f.rjust END, - CASE WHEN s_appr THEN f.ap1 END, CASE WHEN s_appr THEN f.ap2 END, - CASE WHEN s_appr THEN f.ap3 END, CASE WHEN s_appr THEN f.ap4 END, - CASE WHEN s_appr THEN f.ap1+f.ap2+f.ap3+f.ap4 END, - CASE WHEN s_ca THEN f.ca_amt END, CASE WHEN s_ca THEN f.ca_prot END, CASE WHEN s_ca THEN f.ca_note END, - CASE WHEN s_ckk THEN f.ckk_ceil END, CASE WHEN s_ckk THEN f.ckk1 END, CASE WHEN s_ckk THEN f.ckk2 END, - CASE WHEN s_ckk THEN f.ckk3 END, CASE WHEN s_ckk THEN f.ckk4 END, - CASE WHEN s_ckk THEN f.ckk_rf END, CASE WHEN s_ckk THEN f.ckk_dl END, - CASE WHEN s_ckk THEN f.ckk_pp END, CASE WHEN s_ckk THEN f.ckk_pm END, CASE WHEN s_ckk THEN f.ckk_cmt END, - CASE WHEN s_cd THEN f.cd_cp END, CASE WHEN s_cd THEN f.cd_ref END, CASE WHEN s_cd THEN f.cd_add END, - CASE WHEN s_cd THEN f.cd_subj END, CASE WHEN s_cd THEN f.cd_cur END, CASE WHEN s_cd THEN f.cd_ceil END, - CASE WHEN s_cd THEN f.cdq1 END, CASE WHEN s_cd THEN f.cdq2 END, - CASE WHEN s_cd THEN f.cdq3 END, CASE WHEN s_cd THEN f.cdq4 END, - CASE WHEN s_cd THEN f.cd_rf END, CASE WHEN s_cd THEN f.cd_vat END, - CASE WHEN s_cd THEN f.cd_rate END, CASE WHEN s_cd THEN f.cd_fx END, - CASE WHEN s_cd THEN f.cd_dl END, CASE WHEN s_cd THEN f.cd_sch END, - CASE WHEN s_cd THEN f.cd_act END, CASE WHEN s_cd THEN f.cd_cmt2 END, - CASE WHEN s_q1 THEN f.q1_ac END, CASE WHEN s_q1 THEN f.q1_as END, - CASE WHEN s_q1 THEN f.q1_ar END, CASE WHEN s_q1 THEN f.q1_arv END, - CASE WHEN s_q1 THEN f.q1_acmt END, CASE WHEN s_q1 THEN f.cp1 END, - CASE WHEN s_q1 THEN f.q1_pd END, CASE WHEN s_q1 THEN f.q1_pa END, - CASE WHEN s_q1 THEN f.q1_pho END, CASE WHEN s_q1 THEN f.q1_prf END, - CASE WHEN s_q1 THEN f.q1_pcmt END, CASE WHEN s_q1 THEN f.q1_pact END, - CASE WHEN s_q1 THEN COALESCE(f.bk1,0) END, - CASE WHEN s_q1 THEN f.q1_m1 END, CASE WHEN s_q1 THEN f.q1_m2 END, CASE WHEN s_q1 THEN f.q1_m3 END, - CASE WHEN s_q1 THEN f.aq1 END, - CASE WHEN s_q1 THEN f.cp1 - COALESCE(f.bk1,0) END, - CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, - CASE WHEN s_q1 THEN f.q1_tq2 END, CASE WHEN s_q1 THEN f.q1_tq3 END, CASE WHEN s_q1 THEN f.q1_tq4 END, - CASE WHEN s_q1 THEN f.cp1 - f.aq1 - COALESCE(f.q1_tq2,0) - COALESCE(f.q1_tq3,0) - COALESCE(f.q1_tq4,0) END, - CASE WHEN s_q1 THEN f.cp1 - f.aq1 END, - CASE WHEN s_q2 THEN f.q2_reco END, CASE WHEN s_q2 THEN f.q2_ritm END, - CASE WHEN s_q2 THEN f.q2_rinc END, CASE WHEN s_q2 THEN f.q2_rseq END, - CASE WHEN s_q2 THEN f.q2_rcmt END, CASE WHEN s_q2 THEN f.np2 END, - CASE WHEN s_q2 THEN f.q2_ac END, CASE WHEN s_q2 THEN f.q2_as END, - CASE WHEN s_q2 THEN f.q2_ar END, CASE WHEN s_q2 THEN f.q2_arv END, - CASE WHEN s_q2 THEN f.q2_acmt END, CASE WHEN s_q2 THEN f.cp2 END, - CASE WHEN s_q2 THEN f.q2_pd END, CASE WHEN s_q2 THEN f.q2_pa END, - CASE WHEN s_q2 THEN f.q2_pho END, CASE WHEN s_q2 THEN f.q2_prf END, - CASE WHEN s_q2 THEN f.q2_pcmt END, CASE WHEN s_q2 THEN f.q2_pact END, - CASE WHEN s_q2 THEN COALESCE(f.bk2,0) END, - CASE WHEN s_q2 THEN f.q2_m1 END, CASE WHEN s_q2 THEN f.q2_m2 END, CASE WHEN s_q2 THEN f.q2_m3 END, - CASE WHEN s_q2 THEN f.aq2 END, - CASE WHEN s_q2 THEN f.cp2 - COALESCE(f.bk2,0) END, - CASE WHEN s_q2 THEN f.cp2 - f.aq2 END, - CASE WHEN s_q2 THEN f.q2_tq3 END, CASE WHEN s_q2 THEN f.q2_tq4 END, - CASE WHEN s_q2 THEN f.cp2 - f.aq2 - COALESCE(f.q2_tq3,0) - COALESCE(f.q2_tq4,0) END, - CASE WHEN s_q2 THEN f.cp2 - f.aq2 END, - CASE WHEN s_q3 THEN f.q3_reco END, CASE WHEN s_q3 THEN f.q3_ritm END, - CASE WHEN s_q3 THEN f.q3_rinc END, CASE WHEN s_q3 THEN f.q3_rseq END, - CASE WHEN s_q3 THEN f.q3_rcmt END, CASE WHEN s_q3 THEN f.np3 END, - CASE WHEN s_q3 THEN f.q3_ac END, CASE WHEN s_q3 THEN f.q3_as END, - CASE WHEN s_q3 THEN f.q3_ar END, CASE WHEN s_q3 THEN f.q3_arv END, - CASE WHEN s_q3 THEN f.q3_acmt END, CASE WHEN s_q3 THEN f.cp3 END, - CASE WHEN s_q3 THEN f.q3_pd END, CASE WHEN s_q3 THEN f.q3_pa END, - CASE WHEN s_q3 THEN f.q3_pho END, CASE WHEN s_q3 THEN f.q3_prf END, - CASE WHEN s_q3 THEN f.q3_pcmt END, CASE WHEN s_q3 THEN f.q3_pact END, - CASE WHEN s_q3 THEN COALESCE(f.bk3,0) END, - CASE WHEN s_q3 THEN f.q3_m1 END, CASE WHEN s_q3 THEN f.q3_m2 END, CASE WHEN s_q3 THEN f.q3_m3 END, - CASE WHEN s_q3 THEN f.aq3 END, - CASE WHEN s_q3 THEN f.cp3 - COALESCE(f.bk3,0) END, - CASE WHEN s_q3 THEN f.cp3 - f.aq3 END, - CASE WHEN s_q3 THEN f.q3_tq4 END, - CASE WHEN s_q3 THEN f.cp3 - f.aq3 - COALESCE(f.q3_tq4,0) END, - CASE WHEN s_q3 THEN f.cp3 - f.aq3 END, - CASE WHEN s_q4 THEN f.q4_reco END, CASE WHEN s_q4 THEN f.q4_ritm END, - CASE WHEN s_q4 THEN f.q4_rinc END, CASE WHEN s_q4 THEN f.q4_rseq END, - CASE WHEN s_q4 THEN f.q4_rcmt END, CASE WHEN s_q4 THEN f.np4 END, - CASE WHEN s_q4 THEN f.q4_ac END, CASE WHEN s_q4 THEN f.q4_as END, - CASE WHEN s_q4 THEN f.q4_ar END, CASE WHEN s_q4 THEN f.q4_arv END, - CASE WHEN s_q4 THEN f.q4_acmt END, CASE WHEN s_q4 THEN f.cp4 END, - CASE WHEN s_q4 THEN f.q4_pd END, CASE WHEN s_q4 THEN f.q4_pa END, - CASE WHEN s_q4 THEN f.q4_pho END, CASE WHEN s_q4 THEN f.q4_prf END, - CASE WHEN s_q4 THEN f.q4_pcmt END, CASE WHEN s_q4 THEN f.q4_pact END, - CASE WHEN s_q4 THEN COALESCE(f.bk4,0) END, - CASE WHEN s_q4 THEN f.q4_m1 END, CASE WHEN s_q4 THEN f.q4_m2 END, CASE WHEN s_q4 THEN f.q4_m3 END, - CASE WHEN s_q4 THEN f.aq4_no_spod END, - CASE WHEN s_q4 THEN f.q4_spod END, - CASE WHEN s_q4 THEN f.cp4 - COALESCE(f.bk4,0) END, - CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, - CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, - CASE WHEN s_q4 THEN f.cp4 - f.aq4 END, - CASE WHEN s_tot THEN COALESCE(f.tot_aq1,0)+COALESCE(f.tot_aq2,0)+COALESCE(f.tot_aq3,0)+COALESCE(f.tot_aq4,0) END, - CASE WHEN s_tot THEN COALESCE(f.tot_pa1,0)+COALESCE(f.tot_pa2,0)+COALESCE(f.tot_pa3,0)+COALESCE(f.tot_pa4,0) END, - f.tree_path || ARRAY[f.lid] AS _sort, - f.lid::BIGINT AS _k - FROM final_input f - - UNION ALL - - SELECT - CASE t.depth WHEN 0 THEN 'ROOT' WHEN 1 THEN 'GROUP' WHEN 2 THEN 'ITEM' WHEN 3 THEN 'SUB_ITEM' WHEN 4 THEN 'SUB_SUB_ITEM' END::VARCHAR, - t.depth, NULL::INT, - v_year, - CASE - WHEN t.depth < 3 THEN t.item_id - WHEN t.depth = 3 THEN t.parent_item_id - WHEN t.depth = 4 THEN t.grandparent_item_id - END, - CASE WHEN t.depth >= 3 THEN t.item_id ELSE NULL::VARCHAR END, - t.num_group_id, t.name, NULL::VARCHAR, - CASE WHEN s_plan THEN ta.sp1 END, - CASE WHEN s_plan THEN ta.sp2 END, - CASE WHEN s_plan THEN ta.sp3 END, - CASE WHEN s_plan THEN ta.sp4 END, - CASE WHEN s_plan THEN (COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0)) END, - NULL::VARCHAR, - CASE WHEN s_cs THEN ta.scst END, - NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_cs THEN ta.sfy1 END, - CASE WHEN s_cs THEN ta.sfy2 END, - CASE WHEN s_cs THEN ta.sossp END, - NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_seq THEN ta.ss1 END, - CASE WHEN s_seq THEN ta.ss2 END, - CASE WHEN s_seq THEN ta.ss3 END, - CASE WHEN s_seq THEN ta.ss4 END, - CASE WHEN s_seq THEN (COALESCE(ta.ss1,0)+COALESCE(ta.ss2,0)+COALESCE(ta.ss3,0)+COALESCE(ta.ss4,0)) END, - NULL::VARCHAR, - CASE WHEN s_res THEN ta.sr1 END, - CASE WHEN s_res THEN ta.sr2 END, - CASE WHEN s_res THEN ta.sr3 END, - CASE WHEN s_res THEN ta.sr4 END, - CASE WHEN s_res THEN (COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0)) END, - NULL::VARCHAR, - CASE WHEN s_appr THEN (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) END, - CASE WHEN s_appr THEN (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) END, - CASE WHEN s_appr THEN (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) END, - CASE WHEN s_appr THEN (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) END, - CASE WHEN s_appr THEN (COALESCE(ta.sp1,0)+COALESCE(ta.sp2,0)+COALESCE(ta.sp3,0)+COALESCE(ta.sp4,0) - +COALESCE(ta.ss1,0)+COALESCE(ta.ss2,0)+COALESCE(ta.ss3,0)+COALESCE(ta.ss4,0) - +COALESCE(ta.sr1,0)+COALESCE(ta.sr2,0)+COALESCE(ta.sr3,0)+COALESCE(ta.sr4,0)) END, - CASE WHEN s_ca THEN ta.sca END, - NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_ckk THEN ta.sckc END, - CASE WHEN s_ckk THEN ta.sck1 END, - CASE WHEN s_ckk THEN ta.sck2 END, - CASE WHEN s_ckk THEN ta.sck3 END, - CASE WHEN s_ckk THEN ta.sck4 END, - NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, - NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_cd THEN ta.scdc END, - CASE WHEN s_cd THEN ta.scd1 END, - CASE WHEN s_cd THEN ta.scd2 END, - CASE WHEN s_cd THEN ta.scd3 END, - CASE WHEN s_cd THEN ta.scd4 END, - NULL::VARCHAR, NULL::VARCHAR, NULL::NUMERIC, NULL::NUMERIC, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_q1 THEN tb1.ac END, - CASE WHEN s_q1 THEN tb1.as2 END, - CASE WHEN s_q1 THEN tb1.ar END, - CASE WHEN s_q1 THEN tb1.arv END, - NULL::VARCHAR, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) - + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)), 0) - END, - NULL::DATE, - CASE WHEN s_q1 THEN tb1.pa END, - CASE WHEN s_q1 THEN tb1.pho END, - CASE WHEN s_q1 THEN tb1.prf END, - NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_q1 THEN ta.bk1 END, - CASE WHEN s_q1 THEN tb1.m1 END, - CASE WHEN s_q1 THEN tb1.m2 END, - CASE WHEN s_q1 THEN tb1.m3 END, - CASE WHEN s_q1 THEN (COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)) END, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) - + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) - - COALESCE(ta.bk1,0) - END, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) - + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) - - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0) - END, - CASE WHEN s_q1 THEN tb1.tq2 END, - CASE WHEN s_q1 THEN tb1.tq3 END, - CASE WHEN s_q1 THEN tb1.tq4 END, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) - + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) - - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0) - - COALESCE((COALESCE(tb1.tq2,0)+COALESCE(tb1.tq3,0)+COALESCE(tb1.tq4,0)),0) - END, - CASE WHEN s_q1 THEN - (COALESCE(ta.sp1,0)+COALESCE(ta.ss1,0)+COALESCE(ta.sr1,0)) - + COALESCE((COALESCE(tb1.ac,0)+COALESCE(tb1.as2,0)+COALESCE(tb1.ar,0)+COALESCE(tb1.arv,0)),0) - - COALESCE((COALESCE(tb1.m1,0)+COALESCE(tb1.m2,0)+COALESCE(tb1.m3,0)),0) - END, - CASE WHEN s_q2 THEN tb2.reco END, - CASE WHEN s_q2 THEN tb2.ritm END, - CASE WHEN s_q2 THEN tb2.rinc END, - CASE WHEN s_q2 THEN tb2.rseq END, - NULL::VARCHAR, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) - + COALESCE(tb1.tq2, 0) - + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)), 0) - END, - CASE WHEN s_q2 THEN tb2.ac END, - CASE WHEN s_q2 THEN tb2.as2 END, - CASE WHEN s_q2 THEN tb2.ar END, - CASE WHEN s_q2 THEN tb2.arv END, - NULL::VARCHAR, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) - + COALESCE(tb1.tq2, 0) - + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)), 0) - END, - NULL::DATE, - CASE WHEN s_q2 THEN tb2.pa END, - CASE WHEN s_q2 THEN tb2.pho END, - CASE WHEN s_q2 THEN tb2.prf END, - NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_q2 THEN ta.bk2 END, - CASE WHEN s_q2 THEN tb2.m1 END, - CASE WHEN s_q2 THEN tb2.m2 END, - CASE WHEN s_q2 THEN tb2.m3 END, - CASE WHEN s_q2 THEN (COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)) END, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) - + COALESCE(tb1.tq2,0) - + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) - - COALESCE(ta.bk2,0) - END, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) - + COALESCE(tb1.tq2,0) - + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) - - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0) - END, - CASE WHEN s_q2 THEN tb2.tq3 END, - CASE WHEN s_q2 THEN tb2.tq4 END, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) - + COALESCE(tb1.tq2,0) - + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) - - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0) - - COALESCE((COALESCE(tb2.tq3,0)+COALESCE(tb2.tq4,0)),0) - END, - CASE WHEN s_q2 THEN - (COALESCE(ta.sp2,0)+COALESCE(ta.ss2,0)+COALESCE(ta.sr2,0)) - + COALESCE(tb1.tq2,0) - + COALESCE((COALESCE(tb2.reco,0)+COALESCE(tb2.ritm,0)+COALESCE(tb2.rinc,0)+COALESCE(tb2.rseq,0)+COALESCE(tb2.ac,0)+COALESCE(tb2.as2,0)+COALESCE(tb2.ar,0)+COALESCE(tb2.arv,0)),0) - - COALESCE((COALESCE(tb2.m1,0)+COALESCE(tb2.m2,0)+COALESCE(tb2.m3,0)),0) - END, - CASE WHEN s_q3 THEN tb3.reco END, - CASE WHEN s_q3 THEN tb3.ritm END, - CASE WHEN s_q3 THEN tb3.rinc END, - CASE WHEN s_q3 THEN tb3.rseq END, - NULL::VARCHAR, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) - + COALESCE(tb1.tq3, 0) - + COALESCE(tb2.tq3, 0) - + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)), 0) - END, - CASE WHEN s_q3 THEN tb3.ac END, - CASE WHEN s_q3 THEN tb3.as2 END, - CASE WHEN s_q3 THEN tb3.ar END, - CASE WHEN s_q3 THEN tb3.arv END, - NULL::VARCHAR, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) - + COALESCE(tb1.tq3, 0) - + COALESCE(tb2.tq3, 0) - + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)), 0) - END, - NULL::DATE, - CASE WHEN s_q3 THEN tb3.pa END, - CASE WHEN s_q3 THEN tb3.pho END, - CASE WHEN s_q3 THEN tb3.prf END, - NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_q3 THEN ta.bk3 END, - CASE WHEN s_q3 THEN tb3.m1 END, - CASE WHEN s_q3 THEN tb3.m2 END, - CASE WHEN s_q3 THEN tb3.m3 END, - CASE WHEN s_q3 THEN (COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)) END, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) - + COALESCE(tb1.tq3,0) - + COALESCE(tb2.tq3,0) - + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) - - COALESCE(ta.bk3,0) - END, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) - + COALESCE(tb1.tq3,0) - + COALESCE(tb2.tq3,0) - + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) - - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0) - END, - CASE WHEN s_q3 THEN tb3.tq4 END, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) - + COALESCE(tb1.tq3,0) - + COALESCE(tb2.tq3,0) - + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) - - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0) - - COALESCE(COALESCE(tb3.tq4,0),0) - END, - CASE WHEN s_q3 THEN - (COALESCE(ta.sp3,0)+COALESCE(ta.ss3,0)+COALESCE(ta.sr3,0)) - + COALESCE(tb1.tq3,0) - + COALESCE(tb2.tq3,0) - + COALESCE((COALESCE(tb3.reco,0)+COALESCE(tb3.ritm,0)+COALESCE(tb3.rinc,0)+COALESCE(tb3.rseq,0)+COALESCE(tb3.ac,0)+COALESCE(tb3.as2,0)+COALESCE(tb3.ar,0)+COALESCE(tb3.arv,0)),0) - - COALESCE((COALESCE(tb3.m1,0)+COALESCE(tb3.m2,0)+COALESCE(tb3.m3,0)),0) - END, - CASE WHEN s_q4 THEN tb4.reco END, - CASE WHEN s_q4 THEN tb4.ritm END, - CASE WHEN s_q4 THEN tb4.rinc END, - CASE WHEN s_q4 THEN tb4.rseq END, - NULL::VARCHAR, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) - + COALESCE(tb1.tq4, 0) - + COALESCE(tb2.tq4, 0) - + COALESCE(tb3.tq4, 0) - + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)), 0) - END, - CASE WHEN s_q4 THEN tb4.ac END, - CASE WHEN s_q4 THEN tb4.as2 END, - CASE WHEN s_q4 THEN tb4.ar END, - CASE WHEN s_q4 THEN tb4.arv END, - NULL::VARCHAR, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) - + COALESCE(tb1.tq4, 0) - + COALESCE(tb2.tq4, 0) - + COALESCE(tb3.tq4, 0) - + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)), 0) - END, - NULL::DATE, - CASE WHEN s_q4 THEN tb4.pa END, - CASE WHEN s_q4 THEN tb4.pho END, - CASE WHEN s_q4 THEN tb4.prf END, - NULL::VARCHAR, NULL::VARCHAR, - CASE WHEN s_q4 THEN ta.bk4 END, - CASE WHEN s_q4 THEN tb4.m1 END, - CASE WHEN s_q4 THEN tb4.m2 END, - CASE WHEN s_q4 THEN tb4.m3 END, - CASE WHEN s_q4 THEN (COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)) END, - CASE WHEN s_q4 THEN tb4.spod END, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) - + COALESCE(tb1.tq4,0) - + COALESCE(tb2.tq4,0) - + COALESCE(tb3.tq4,0) - + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) - - COALESCE(ta.bk4,0) - END, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) - + COALESCE(tb1.tq4,0) - + COALESCE(tb2.tq4,0) - + COALESCE(tb3.tq4,0) - + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) - - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0) - END, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) - + COALESCE(tb1.tq4,0) - + COALESCE(tb2.tq4,0) - + COALESCE(tb3.tq4,0) - + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) - - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0) - END, - CASE WHEN s_q4 THEN - (COALESCE(ta.sp4,0)+COALESCE(ta.ss4,0)+COALESCE(ta.sr4,0)) - + COALESCE(tb1.tq4,0) - + COALESCE(tb2.tq4,0) - + COALESCE(tb3.tq4,0) - + COALESCE((COALESCE(tb4.reco,0)+COALESCE(tb4.ritm,0)+COALESCE(tb4.rinc,0)+COALESCE(tb4.rseq,0)+COALESCE(tb4.ac,0)+COALESCE(tb4.as2,0)+COALESCE(tb4.ar,0)+COALESCE(tb4.arv,0)),0) - - COALESCE((COALESCE(tb4.m1,0)+COALESCE(tb4.m2,0)+COALESCE(tb4.m3,0)+COALESCE(tb4.spod,0)),0) - END, - CASE WHEN s_tot THEN (COALESCE(tt.fq1,0)+COALESCE(tt.fq2,0)+COALESCE(tt.fq3,0)+COALESCE(tt.fq4,0)) END, - CASE WHEN s_tot THEN tt.pay END, - t.path AS _sort, - -t.id::BIGINT - - FROM tw_f t - LEFT JOIN tw_agg ta ON ta.id = t.id - LEFT JOIN tw_aq1 tb1 ON tb1.id = t.id - LEFT JOIN tw_aq2 tb2 ON tb2.id = t.id - LEFT JOIN tw_aq3 tb3 ON tb3.id = t.id - LEFT JOIN tw_aq4 tb4 ON tb4.id = t.id - LEFT JOIN tw_atot tt ON tt.id = t.id - ) sub(row_type, depth, line_id, col_b_year, col_c_section, col_d_item_id, col_e_num_group, col_f_name, col_g_internal_order, col_h_plan_q1, col_i_plan_q2, col_j_plan_q3, col_k_plan_q4, col_l_plan_year, col_m_plan_comment, col_n_cs_total, col_o_cs_counterparty, col_p_cs_deadline, col_q_cs_comment, col_r_cs_future_y1, col_s_cs_future_y2, col_t_cs_other_ssp, col_v_al_order, col_w_al_property, col_y_seq_q1, col_z_seq_q2, col_aa_seq_q3, col_ab_seq_q4, col_ac_seq_year, col_ad_seq_justification, col_af_res_q1, col_ag_res_q2, col_ah_res_q3, col_ai_res_q4, col_aj_res_year, col_ak_res_justification, col_am_approved_q1, col_an_approved_q2, col_ao_approved_q3, col_ap_approved_q4, col_aq_approved_year, col_as_ca_approved, col_at_ca_protocol, col_au_ca_note, col_aw_ckk_ceiling, col_ax_ckk_exp_q1, col_ay_ckk_exp_q2, col_az_ckk_exp_q3, col_ba_ckk_exp_q4, col_bb_ckk_rf_sched, col_bc_ckk_deadline, col_bd_ckk_proc_plan, col_be_ckk_proc_meth, col_bf_ckk_comment, col_bh_cd_counterparty, col_bi_cd_reference, col_bj_cd_addenda, col_bk_cd_subject, col_bl_cd_currency, col_bm_cd_ceiling, col_bn_cd_exp_q1, col_bo_cd_exp_q2, col_bp_cd_exp_q3, col_bq_cd_exp_q4, col_br_cd_rf_sched, col_bs_cd_vat, col_bt_cd_rate, col_bu_cd_amount_fx, col_bv_cd_deadline, col_bw_cd_scheme, col_bx_cd_act, col_by_cd_comment, col_ca_q1_adj_current, col_cb_q1_adj_ssp, col_cc_q1_adj_rf, col_cd_q1_adj_reserve, col_ce_q1_adj_comment, col_cf_q1_corrected_plan, col_ch_q1_pay_date, col_ci_q1_pay_amount, col_cj_q1_pay_ho, col_ck_q1_pay_rf, col_cl_q1_pay_comment, col_cm_q1_pay_act, col_co_q1_booking, col_cp_q1_actual_m1, col_cq_q1_actual_m2, col_cr_q1_actual_m3, col_cs_q1_actual_quarter, col_ct_q1_rem_booking, col_cu_q1_rem_actual, col_cw_q1_trans_q2, col_cx_q1_trans_q3, col_cy_q1_trans_q4, col_cz_q1_economy, col_da_q1_total, col_dc_q2_rev_eco, col_dd_q2_rev_item, col_de_q2_rev_inc, col_df_q2_rev_seq, col_dg_q2_rev_comment, col_dh_q2_new_plan, col_dj_q2_adj_current, col_dk_q2_adj_ssp, col_dl_q2_adj_rf, col_dm_q2_adj_reserve, col_dn_q2_adj_comment, col_do_q2_corrected_plan, col_dq_q2_pay_date, col_dr_q2_pay_amount, col_ds_q2_pay_ho, col_dt_q2_pay_rf, col_du_q2_pay_comment, col_dv_q2_pay_act, col_dx_q2_booking, col_dy_q2_actual_m1, col_dz_q2_actual_m2, col_ea_q2_actual_m3, col_eb_q2_actual_quarter, col_ec_q2_rem_booking, col_ed_q2_rem_actual, col_ef_q2_trans_q3, col_eg_q2_trans_q4, col_eh_q2_economy, col_ei_q2_total, col_ek_q3_rev_eco, col_el_q3_rev_item, col_em_q3_rev_inc, col_en_q3_rev_seq, col_eo_q3_rev_comment, col_ep_q3_new_plan, col_er_q3_adj_current, col_es_q3_adj_ssp, col_et_q3_adj_rf, col_eu_q3_adj_reserve, col_ev_q3_adj_comment, col_ew_q3_corrected_plan, col_ey_q3_pay_date, col_ez_q3_pay_amount, col_fa_q3_pay_ho, col_fb_q3_pay_rf, col_fc_q3_pay_comment, col_fd_q3_pay_act, col_ff_q3_booking, col_fg_q3_actual_m1, col_fh_q3_actual_m2, col_fi_q3_actual_m3, col_fj_q3_actual_quarter, col_fk_q3_rem_booking, col_fl_q3_rem_actual, col_fn_q3_trans_q4, col_fo_q3_economy, col_fp_q3_total, col_fr_q4_rev_eco, col_fs_q4_rev_item, col_ft_q4_rev_inc, col_fu_q4_rev_seq, col_fv_q4_rev_comment, col_fw_q4_new_plan, col_fy_q4_adj_current, col_fz_q4_adj_ssp, col_ga_q4_adj_rf, col_gb_q4_adj_reserve, col_gc_q4_adj_comment, col_gd_q4_corrected_plan, col_gf_q4_pay_date, col_gg_q4_pay_amount, col_gh_q4_pay_ho, col_gi_q4_pay_rf, col_gj_q4_pay_comment, col_gk_q4_pay_act, col_gm_q4_booking, col_gn_q4_actual_m1, col_go_q4_actual_m2, col_gp_q4_actual_m3, col_gq_q4_actual_quarter, col_gr_q4_actual_spod, col_gs_q4_rem_booking, col_gt_q4_rem_actual, col_gv_q4_economy, col_gw_q4_total, col_gz_fact_year, col_hb_pay_year, _sort_path, _k) - JOIN sk ON sk.k = sub._k - ORDER BY sk.rnk; - -END; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.v_form2_sheet_jsonb(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) - RETURNS TABLE(row_type character varying, depth integer, line_id integer, header jsonb, plan_data jsonb, seq_dfip_data jsonb, seq_ssp_data jsonb, approved_data jsonb, contract_data jsonb, booking_data jsonb, contract_summary jsonb, allocation_data jsonb, collegial_data jsonb, ckk_data jsonb, q1_data jsonb, q2_data jsonb, q3_data jsonb, q4_data jsonb, totals_data jsonb, _sort_path integer[], _sort_rank bigint) - LANGUAGE sql - STABLE -AS $function$ - WITH flags AS ( - SELECT - (p_sections IS NULL OR 'plan' = ANY(p_sections)) AS s_plan, - (p_sections IS NULL OR 'seq_dfip' = ANY(p_sections)) AS s_seq_d, - (p_sections IS NULL OR 'seq_ssp' = ANY(p_sections)) AS s_seq_s, - (p_sections IS NULL OR 'approved' = ANY(p_sections)) AS s_appr, - (p_sections IS NULL OR 'contract' = ANY(p_sections)) AS s_cd, - (p_sections IS NULL OR 'booking' = ANY(p_sections)) AS s_book, - (p_sections IS NULL OR 'contract_summary' = ANY(p_sections)) AS s_cs, - (p_sections IS NULL OR 'allocation' = ANY(p_sections)) AS s_al, - (p_sections IS NULL OR 'collegial' = ANY(p_sections)) AS s_ca, - (p_sections IS NULL OR 'ckk' = ANY(p_sections)) AS s_ckk, - (p_sections IS NULL OR 'q1' = ANY(p_sections)) AS s_q1, - (p_sections IS NULL OR 'q2' = ANY(p_sections)) AS s_q2, - (p_sections IS NULL OR 'q3' = ANY(p_sections)) AS s_q3, - (p_sections IS NULL OR 'q4' = ANY(p_sections)) AS s_q4, - (p_sections IS NULL OR 'totals' = ANY(p_sections)) AS s_tot - ) - SELECT - s.row_type, s.depth, s.line_id, - - jsonb_build_object( - 'section_code', s.col_section_code, - 'item_id', s.col_item_id, - 'num_group', s.col_num_group_id, - 'name', s.col_name, - 'vsp_id', s.col_vsp_id, - 'vsp_address', s.col_vsp_address, - 'internal_order', s.col_internal_order, - 'expense_item_id', CASE WHEN s.row_type = 'INPUT' - THEN s._sort_path[array_upper(s._sort_path,1)-1] - ELSE s._sort_path[array_upper(s._sort_path,1)] END - ) AS header, - - CASE WHEN f.s_plan THEN jsonb_build_object( - 'q1', s.col_plan_q1, 'q2', s.col_plan_q2, - 'q3', s.col_plan_q3, 'q4', s.col_plan_q4, - 'year', s.col_plan_year, 'comment', s.col_plan_comment - ) END AS plan_data, - - CASE WHEN f.s_seq_d THEN jsonb_build_object( - 'q1', s.col_seq_dfip_q1, 'q2', s.col_seq_dfip_q2, - 'q3', s.col_seq_dfip_q3, 'q4', s.col_seq_dfip_q4, - 'year', s.col_seq_dfip_year, - 'justification', s.col_seq_dfip_just - ) END AS seq_dfip_data, - - CASE WHEN f.s_seq_s THEN jsonb_build_object( - 'q1', s.col_seq_ssp_q1, 'q2', s.col_seq_ssp_q2, - 'q3', s.col_seq_ssp_q3, 'q4', s.col_seq_ssp_q4, - 'year', s.col_seq_ssp_year, - 'justification', s.col_seq_ssp_just - ) END AS seq_ssp_data, - - CASE WHEN f.s_appr THEN jsonb_build_object( - 'q1', s.col_appr_q1, 'q2', s.col_appr_q2, - 'q3', s.col_appr_q3, 'q4', s.col_appr_q4, - 'year', s.col_appr_year - ) END AS approved_data, - - CASE WHEN f.s_cd THEN jsonb_build_object( - 'counterparty', s.col_cd_counterparty, - 'reference', s.col_cd_reference, - 'addenda', s.col_cd_addenda, - 'date', TO_CHAR(s.col_cd_date, 'DD.MM.YYYY'), - 'subject', s.col_cd_subject, - 'currency', s.col_cd_currency, - 'ceiling', s.col_cd_ceiling, - 'q1', s.col_cd_exp_q1, - 'q2', s.col_cd_exp_q2, - 'q3', s.col_cd_exp_q3, - 'q4', s.col_cd_exp_q4, - 'rf_schedule', s.col_cd_rf_sched, - 'vat_rate', s.col_cd_vat_rate, - 'exchange_rate', s.col_cd_exchange_rate, - 'amount_foreign', s.col_cd_amount_foreign, - 'deadline', s.col_cd_deadline, - 'scheme', s.col_cd_scheme, - 'act', s.col_cd_act, - 'comment', s.col_cd_comment - ) END AS contract_data, - - CASE WHEN f.s_book THEN jsonb_build_object( - 'y2026', jsonb_build_object('q1', s.col_book_q1, 'q2', s.col_book_q2, 'q3', s.col_book_q3, 'q4', s.col_book_q4), - 'y2027', jsonb_build_object('q1', s.col_book_next_q1, 'q2', s.col_book_next_q2, 'q3', s.col_book_next_q3, 'q4', s.col_book_next_q4) - ) END AS booking_data, - - CASE WHEN f.s_cs THEN jsonb_build_object( - 'total', s.col_cs_total, - 'counterparty', s.col_cs_counterparty, - 'deadline', s.col_cs_deadline, - 'comment', s.col_cs_comment, - 'future_y1', s.col_cs_future_y1, - 'future_y2', s.col_cs_future_y2, - 'other_ssp', s.col_cs_other_ssp - ) END AS contract_summary, - - CASE WHEN f.s_al THEN jsonb_build_object( - 'contract_ref', s.col_al_contract_ref, - 'purpose', s.col_al_purpose, - 'order', s.col_al_order, - 'property', s.col_al_property - ) END AS allocation_data, - - CASE WHEN f.s_ca THEN jsonb_build_object( - 'approved', s.col_ca_approved, - 'protocol', s.col_ca_protocol, - 'note', s.col_ca_note - ) END AS collegial_data, - - CASE WHEN f.s_ckk THEN jsonb_build_object( - 'ceiling', s.col_ckk_ceiling, - 'rf_schedule', s.col_ckk_rf_sched, - 'deadline', s.col_ckk_deadline, - 'proc_plan', s.col_ckk_proc_plan, - 'proc_method', s.col_ckk_proc_meth, - 'comment', s.col_ckk_comment - ) END AS ckk_data, - - CASE WHEN f.s_q1 THEN jsonb_build_object( - 'adj_current', s.col_q1_adj_current, - 'adj_ssp', s.col_q1_adj_ssp, - 'adj_rf', s.col_q1_adj_rf, - 'adj_reserve', s.col_q1_adj_reserve, - 'adj_comment', s.col_q1_adj_comment, - 'corrected_plan', s.col_q1_corrected_plan, - 'pay_date', TO_CHAR(s.col_q1_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_q1_pay_amount, - 'pay_ho', s.col_q1_pay_ho, - 'pay_rf', s.col_q1_pay_rf, - 'pay_comment', s.col_q1_pay_comment, - 'pay_act', s.col_q1_pay_act, - 'booking', s.col_q1_booking, - 'actual_m1', s.col_q1_actual_m1, - 'actual_m2', s.col_q1_actual_m2, - 'actual_m3', s.col_q1_actual_m3, - 'actual_quarter', s.col_q1_actual_quarter, - 'residual_after_booking', s.col_q1_residual_after_booking, - 'residual_after_actual', s.col_q1_residual_after_actual, - 'transfer_q2', s.col_q1_transfer_q2, - 'transfer_q2_delay_acts', s.col_q1_transfer_q2_delay_acts, - 'transfer_q2_delay_procurement', s.col_q1_transfer_q2_delay_procurement, - 'transfer_q2_economy_rf', s.col_q1_transfer_q2_economy_rf, - 'transfer_next_comment', s.col_q1_transfer_next_comment, - 'transfer_q3', s.col_q1_transfer_q3, - 'transfer_q4', s.col_q1_transfer_q4, - 'transfer_far_comment', s.col_q1_transfer_far_comment, - 'transfer_econ', s.col_q1_transfer_econ, - 'total', s.col_q1_total - ) END AS q1_data, - - CASE WHEN f.s_q2 THEN jsonb_build_object( - 'target_change', s.col_q2_target_change, - 'base_correction', s.col_q2_base_correction, - 'base_correction_comment', s.col_q2_base_correction_comment, - 'revision_inc', s.col_q2_revision_inc, - 'revision_seq', s.col_q2_revision_seq, - 'revision_comment', s.col_q2_revision_comment, - 'new_plan', s.col_q2_new_plan, - 'adj_current', s.col_q2_adj_current, - 'adj_ssp', s.col_q2_adj_ssp, - 'adj_rf', s.col_q2_adj_rf, - 'adj_reserve', s.col_q2_adj_reserve, - 'adj_comment', s.col_q2_adj_comment, - 'corrected_plan', s.col_q2_corrected_plan, - 'pay_date', TO_CHAR(s.col_q2_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_q2_pay_amount, - 'pay_ho', s.col_q2_pay_ho, - 'pay_rf', s.col_q2_pay_rf, - 'pay_comment', s.col_q2_pay_comment, - 'pay_act', s.col_q2_pay_act, - 'booking', s.col_q2_booking, - 'actual_m1', s.col_q2_actual_m1, - 'actual_m2', s.col_q2_actual_m2, - 'actual_m3', s.col_q2_actual_m3, - 'actual_quarter', s.col_q2_actual_quarter, - 'residual_after_booking', s.col_q2_residual_after_booking, - 'residual_after_actual', s.col_q2_residual_after_actual, - 'transfer_q3', s.col_q2_transfer_q3, - 'transfer_q3_delay_acts', s.col_q2_transfer_q3_delay_acts, - 'transfer_q3_delay_procurement', s.col_q2_transfer_q3_delay_procurement, - 'transfer_q3_economy_rf', s.col_q2_transfer_q3_economy_rf, - 'transfer_next_comment', s.col_q2_transfer_next_comment, - 'transfer_q4', s.col_q2_transfer_q4, - 'transfer_far_comment', s.col_q2_transfer_far_comment, - 'transfer_econ', s.col_q2_transfer_econ, - 'total', s.col_q2_total - ) END AS q2_data, - - CASE WHEN f.s_q3 THEN jsonb_build_object( - 'target_change', s.col_q3_target_change, - 'base_correction', s.col_q3_base_correction, - 'base_correction_comment', s.col_q3_base_correction_comment, - 'revision_inc', s.col_q3_revision_inc, - 'revision_seq', s.col_q3_revision_seq, - 'revision_comment', s.col_q3_revision_comment, - 'new_plan', s.col_q3_new_plan, - 'adj_current', s.col_q3_adj_current, - 'adj_ssp', s.col_q3_adj_ssp, - 'adj_rf', s.col_q3_adj_rf, - 'adj_reserve', s.col_q3_adj_reserve, - 'adj_comment', s.col_q3_adj_comment, - 'corrected_plan', s.col_q3_corrected_plan, - 'pay_date', TO_CHAR(s.col_q3_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_q3_pay_amount, - 'pay_ho', s.col_q3_pay_ho, - 'pay_rf', s.col_q3_pay_rf, - 'pay_comment', s.col_q3_pay_comment, - 'pay_act', s.col_q3_pay_act, - 'booking', s.col_q3_booking, - 'actual_m1', s.col_q3_actual_m1, - 'actual_m2', s.col_q3_actual_m2, - 'actual_m3', s.col_q3_actual_m3, - 'actual_quarter', s.col_q3_actual_quarter, - 'residual_after_booking', s.col_q3_residual_after_booking, - 'residual_after_actual', s.col_q3_residual_after_actual, - 'transfer_q4', s.col_q3_transfer_q4, - 'transfer_q4_delay_acts', s.col_q3_transfer_q4_delay_acts, - 'transfer_q4_delay_procurement', s.col_q3_transfer_q4_delay_procurement, - 'transfer_q4_economy_rf', s.col_q3_transfer_q4_economy_rf, - 'transfer_next_comment', s.col_q3_transfer_next_comment, - 'transfer_econ', s.col_q3_transfer_econ, - 'total', s.col_q3_total - ) END AS q3_data, - - CASE WHEN f.s_q4 THEN jsonb_build_object( - 'target_change', s.col_q4_target_change, - 'base_correction', s.col_q4_base_correction, - 'base_correction_comment', s.col_q4_base_correction_comment, - 'revision_inc', s.col_q4_revision_inc, - 'revision_seq', s.col_q4_revision_seq, - 'revision_comment', s.col_q4_revision_comment, - 'new_plan', s.col_q4_new_plan, - 'adj_current', s.col_q4_adj_current, - 'adj_ssp', s.col_q4_adj_ssp, - 'adj_rf', s.col_q4_adj_rf, - 'adj_reserve', s.col_q4_adj_reserve, - 'adj_comment', s.col_q4_adj_comment, - 'corrected_plan', s.col_q4_corrected_plan, - 'pay_date', TO_CHAR(s.col_q4_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_q4_pay_amount, - 'pay_ho', s.col_q4_pay_ho, - 'pay_rf', s.col_q4_pay_rf, - 'pay_comment', s.col_q4_pay_comment, - 'pay_act', s.col_q4_pay_act, - 'booking', s.col_q4_booking, - 'actual_m1', s.col_q4_actual_m1, - 'actual_m2', s.col_q4_actual_m2, - 'actual_m3', s.col_q4_actual_m3, - 'actual_spod', s.col_q4_actual_spod, - 'actual_quarter', s.col_q4_actual_quarter, - 'residual_after_booking', s.col_q4_residual_after_booking, - 'residual_after_actual', s.col_q4_residual_after_actual, - 'transfer_econ', s.col_q4_transfer_econ, - 'total', s.col_q4_total - ) END AS q4_data, - - CASE WHEN f.s_tot THEN jsonb_build_object( - 'fact_year', s.col_fact_year, - 'pay_year', s.col_pay_year, - 'economy_year', s.col_economy_year - ) END AS totals_data, - - s._sort_path, - s._sort_rank - FROM v3.v_form2_sheet_sections(p_form_id, p_sheet, p_sections, p_focus_lines) s - CROSS JOIN flags f - ORDER BY s._sort_rank; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.v_form1_sheet_jsonb(p_form_id integer, p_sheet character varying, p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) - RETURNS TABLE(row_type character varying, depth integer, line_id integer, header jsonb, plan_data jsonb, contract_summary jsonb, allocation_data jsonb, sequestration_data jsonb, reserve_data jsonb, approved_data jsonb, collegial_data jsonb, ckk_data jsonb, contract_detail jsonb, q1_data jsonb, q2_data jsonb, q3_data jsonb, q4_data jsonb, totals_data jsonb, _sort_path integer[], _sort_rank bigint) - LANGUAGE sql - STABLE - SET search_path TO 'v3', 'pg_catalog' -AS $function$ - WITH flags AS ( - SELECT - (p_sections IS NULL OR 'plan' = ANY(p_sections)) AS s_plan, - (p_sections IS NULL OR 'contract_summary' = ANY(p_sections)) AS s_cs, - (p_sections IS NULL OR 'allocation' = ANY(p_sections)) AS s_al, - (p_sections IS NULL OR 'sequestration' = ANY(p_sections)) AS s_seq, - (p_sections IS NULL OR 'reserve' = ANY(p_sections)) AS s_res, - (p_sections IS NULL OR 'approved' = ANY(p_sections)) AS s_appr, - (p_sections IS NULL OR 'collegial' = ANY(p_sections)) AS s_ca, - (p_sections IS NULL OR 'ckk' = ANY(p_sections)) AS s_ckk, - (p_sections IS NULL OR 'contract_detail' = ANY(p_sections)) AS s_cd, - (p_sections IS NULL OR 'q1' = ANY(p_sections)) AS s_q1, - (p_sections IS NULL OR 'q2' = ANY(p_sections)) AS s_q2, - (p_sections IS NULL OR 'q3' = ANY(p_sections)) AS s_q3, - (p_sections IS NULL OR 'q4' = ANY(p_sections)) AS s_q4, - (p_sections IS NULL OR 'totals' = ANY(p_sections)) AS s_tot - ) - SELECT - s.row_type, s.depth, s.line_id, - - jsonb_build_object( - 'year', s.col_B_year, - 'section', s.col_C_section, - 'item_id', s.col_D_item_id, - 'num_group', s.col_E_num_group, - 'name', s.col_F_name, - 'internal_order', s.col_G_internal_order, - 'expense_item_id', CASE WHEN s.row_type = 'INPUT' - THEN s._sort_path[array_upper(s._sort_path,1)-1] - ELSE s._sort_path[array_upper(s._sort_path,1)] END - ) AS header, - - CASE WHEN f.s_plan THEN jsonb_build_object( - 'q1', s.col_H_plan_q1, - 'q2', s.col_I_plan_q2, - 'q3', s.col_J_plan_q3, - 'q4', s.col_K_plan_q4, - 'year', s.col_L_plan_year, - 'comment', s.col_M_plan_comment - ) END AS plan_data, - - CASE WHEN f.s_cs THEN jsonb_build_object( - 'total', s.col_N_cs_total, - 'counterparty', s.col_O_cs_counterparty, - 'deadline', s.col_P_cs_deadline, - 'comment', s.col_Q_cs_comment, - 'future_y1', s.col_R_cs_future_y1, - 'future_y2', s.col_S_cs_future_y2, - 'other_ssp', s.col_T_cs_other_ssp - ) END AS contract_summary, - - CASE WHEN f.s_al THEN jsonb_build_object( - 'order', s.col_V_al_order, - 'property', s.col_W_al_property - ) END AS allocation_data, - - CASE WHEN f.s_seq THEN jsonb_build_object( - 'q1', s.col_Y_seq_q1, - 'q2', s.col_Z_seq_q2, - 'q3', s.col_AA_seq_q3, - 'q4', s.col_AB_seq_q4, - 'year', s.col_AC_seq_year, - 'justification', s.col_AD_seq_justification - ) END AS sequestration_data, - - CASE WHEN f.s_res THEN jsonb_build_object( - 'q1', s.col_AF_res_q1, - 'q2', s.col_AG_res_q2, - 'q3', s.col_AH_res_q3, - 'q4', s.col_AI_res_q4, - 'year', s.col_AJ_res_year, - 'justification', s.col_AK_res_justification - ) END AS reserve_data, - - CASE WHEN f.s_appr THEN jsonb_build_object( - 'q1', s.col_AM_approved_q1, - 'q2', s.col_AN_approved_q2, - 'q3', s.col_AO_approved_q3, - 'q4', s.col_AP_approved_q4, - 'year', s.col_AQ_approved_year - ) END AS approved_data, - - CASE WHEN f.s_ca THEN jsonb_build_object( - 'approved', s.col_AS_ca_approved, - 'protocol', s.col_AT_ca_protocol, - 'note', s.col_AU_ca_note - ) END AS collegial_data, - - CASE WHEN f.s_ckk THEN jsonb_build_object( - 'ceiling', s.col_AW_ckk_ceiling, - 'q1', s.col_AX_ckk_exp_q1, - 'q2', s.col_AY_ckk_exp_q2, - 'q3', s.col_AZ_ckk_exp_q3, - 'q4', s.col_BA_ckk_exp_q4, - 'rf_schedule', s.col_BB_ckk_rf_sched, - 'deadline', s.col_BC_ckk_deadline, - 'proc_plan', s.col_BD_ckk_proc_plan, - 'proc_method', s.col_BE_ckk_proc_meth, - 'comment', s.col_BF_ckk_comment - ) END AS ckk_data, - - CASE WHEN f.s_cd THEN jsonb_build_object( - 'counterparty', s.col_BH_cd_counterparty, - 'reference', s.col_BI_cd_reference, - 'addenda', s.col_BJ_cd_addenda, - 'subject', s.col_BK_cd_subject, - 'currency', s.col_BL_cd_currency, - 'ceiling', s.col_BM_cd_ceiling, - 'q1', s.col_BN_cd_exp_q1, - 'q2', s.col_BO_cd_exp_q2, - 'q3', s.col_BP_cd_exp_q3, - 'q4', s.col_BQ_cd_exp_q4, - 'rf_schedule', s.col_BR_cd_rf_sched, - 'vat_rate', s.col_BS_cd_vat, - 'exchange_rate', s.col_BT_cd_rate, - 'amount_foreign', s.col_BU_cd_amount_fx, - 'deadline', s.col_BV_cd_deadline, - 'payment_scheme', s.col_BW_cd_scheme, - 'act', s.col_BX_cd_act, - 'comment', s.col_BY_cd_comment - ) END AS contract_detail, - - CASE WHEN f.s_q1 THEN jsonb_build_object( - 'adj_current', s.col_CA_q1_adj_current, - 'adj_ssp', s.col_CB_q1_adj_ssp, - 'adj_rf', s.col_CC_q1_adj_rf, - 'adj_reserve', s.col_CD_q1_adj_reserve, - 'adj_comment', s.col_CE_q1_adj_comment, - 'corrected_plan', s.col_CF_q1_corrected_plan, - 'pay_date', TO_CHAR(s.col_CH_q1_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_CI_q1_pay_amount, - 'pay_ho', s.col_CJ_q1_pay_ho, - 'pay_rf', s.col_CK_q1_pay_rf, - 'pay_comment', s.col_CL_q1_pay_comment, - 'pay_act', s.col_CM_q1_pay_act, - 'booking', s.col_CO_q1_booking, - 'actual_m1', s.col_CP_q1_actual_m1, - 'actual_m2', s.col_CQ_q1_actual_m2, - 'actual_m3', s.col_CR_q1_actual_m3, - 'actual_quarter', s.col_CS_q1_actual_quarter, - 'rem_booking', s.col_CT_q1_rem_booking, - 'rem_actual', s.col_CU_q1_rem_actual, - 'transfer_q2', s.col_CW_q1_trans_q2, - 'transfer_q3', s.col_CX_q1_trans_q3, - 'transfer_q4', s.col_CY_q1_trans_q4, - 'economy', s.col_CZ_q1_economy, - 'total', s.col_DA_q1_total - ) END AS q1_data, - - CASE WHEN f.s_q2 THEN jsonb_build_object( - 'rev_eco', s.col_DC_q2_rev_eco, - 'rev_item', s.col_DD_q2_rev_item, - 'rev_inc', s.col_DE_q2_rev_inc, - 'rev_seq', s.col_DF_q2_rev_seq, - 'rev_comment', s.col_DG_q2_rev_comment, - 'new_plan', s.col_DH_q2_new_plan, - 'adj_current', s.col_DJ_q2_adj_current, - 'adj_ssp', s.col_DK_q2_adj_ssp, - 'adj_rf', s.col_DL_q2_adj_rf, - 'adj_reserve', s.col_DM_q2_adj_reserve, - 'adj_comment', s.col_DN_q2_adj_comment, - 'corrected_plan', s.col_DO_q2_corrected_plan, - 'pay_date', TO_CHAR(s.col_DQ_q2_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_DR_q2_pay_amount, - 'pay_ho', s.col_DS_q2_pay_ho, - 'pay_rf', s.col_DT_q2_pay_rf, - 'pay_comment', s.col_DU_q2_pay_comment, - 'pay_act', s.col_DV_q2_pay_act, - 'booking', s.col_DX_q2_booking, - 'actual_m1', s.col_DY_q2_actual_m1, - 'actual_m2', s.col_DZ_q2_actual_m2, - 'actual_m3', s.col_EA_q2_actual_m3, - 'actual_quarter', s.col_EB_q2_actual_quarter, - 'rem_booking', s.col_EC_q2_rem_booking, - 'rem_actual', s.col_ED_q2_rem_actual, - 'transfer_q3', s.col_EF_q2_trans_q3, - 'transfer_q4', s.col_EG_q2_trans_q4, - 'economy', s.col_EH_q2_economy, - 'total', s.col_EI_q2_total - ) END AS q2_data, - - CASE WHEN f.s_q3 THEN jsonb_build_object( - 'rev_eco', s.col_EK_q3_rev_eco, - 'rev_item', s.col_EL_q3_rev_item, - 'rev_inc', s.col_EM_q3_rev_inc, - 'rev_seq', s.col_EN_q3_rev_seq, - 'rev_comment', s.col_EO_q3_rev_comment, - 'new_plan', s.col_EP_q3_new_plan, - 'adj_current', s.col_ER_q3_adj_current, - 'adj_ssp', s.col_ES_q3_adj_ssp, - 'adj_rf', s.col_ET_q3_adj_rf, - 'adj_reserve', s.col_EU_q3_adj_reserve, - 'adj_comment', s.col_EV_q3_adj_comment, - 'corrected_plan', s.col_EW_q3_corrected_plan, - 'pay_date', TO_CHAR(s.col_EY_q3_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_EZ_q3_pay_amount, - 'pay_ho', s.col_FA_q3_pay_ho, - 'pay_rf', s.col_FB_q3_pay_rf, - 'pay_comment', s.col_FC_q3_pay_comment, - 'pay_act', s.col_FD_q3_pay_act, - 'booking', s.col_FF_q3_booking, - 'actual_m1', s.col_FG_q3_actual_m1, - 'actual_m2', s.col_FH_q3_actual_m2, - 'actual_m3', s.col_FI_q3_actual_m3, - 'actual_quarter', s.col_FJ_q3_actual_quarter, - 'rem_booking', s.col_FK_q3_rem_booking, - 'rem_actual', s.col_FL_q3_rem_actual, - 'transfer_q4', s.col_FN_q3_trans_q4, - 'economy', s.col_FO_q3_economy, - 'total', s.col_FP_q3_total - ) END AS q3_data, - - CASE WHEN f.s_q4 THEN jsonb_build_object( - 'rev_eco', s.col_FR_q4_rev_eco, - 'rev_item', s.col_FS_q4_rev_item, - 'rev_inc', s.col_FT_q4_rev_inc, - 'rev_seq', s.col_FU_q4_rev_seq, - 'rev_comment', s.col_FV_q4_rev_comment, - 'new_plan', s.col_FW_q4_new_plan, - 'adj_current', s.col_FY_q4_adj_current, - 'adj_ssp', s.col_FZ_q4_adj_ssp, - 'adj_rf', s.col_GA_q4_adj_rf, - 'adj_reserve', s.col_GB_q4_adj_reserve, - 'adj_comment', s.col_GC_q4_adj_comment, - 'corrected_plan', s.col_GD_q4_corrected_plan, - 'pay_date', TO_CHAR(s.col_GF_q4_pay_date, 'DD.MM.YYYY'), - 'pay_amount', s.col_GG_q4_pay_amount, - 'pay_ho', s.col_GH_q4_pay_ho, - 'pay_rf', s.col_GI_q4_pay_rf, - 'pay_comment', s.col_GJ_q4_pay_comment, - 'pay_act', s.col_GK_q4_pay_act, - 'booking', s.col_GM_q4_booking, - 'actual_m1', s.col_GN_q4_actual_m1, - 'actual_m2', s.col_GO_q4_actual_m2, - 'actual_m3', s.col_GP_q4_actual_m3, - 'actual_quarter', s.col_GQ_q4_actual_quarter, - 'actual_spod', s.col_GR_q4_actual_spod, - 'rem_booking', s.col_GS_q4_rem_booking, - 'rem_actual', s.col_GT_q4_rem_actual, - 'economy', s.col_GV_q4_economy, - 'total', s.col_GW_q4_total - ) END AS q4_data, - - CASE WHEN f.s_tot THEN jsonb_build_object( - 'fact_year', s.col_GZ_fact_year, - 'pay_year', s.col_HB_pay_year - ) END AS totals_data, - - s._sort_path, - s._sort_rank - FROM v_form1_sheet_sections(p_form_id, p_sheet, p_direction, p_sections, p_focus_lines) s - CROSS JOIN flags f - ORDER BY s._sort_rank; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.v_form2_view(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_focus_lines integer[] DEFAULT NULL::integer[]) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE plpgsql - STABLE -AS $function$ -BEGIN - - - IF p_sheet IN ('AHR','CAP','OPER') THEN - RETURN QUERY - SELECT - j.row_type, - j.depth, - j._sort_rank AS sort_order, - jsonb_build_object( - 'line_id', j.line_id, - 'header', j.header, - 'plan', j.plan_data, - 'seq_dfip', j.seq_dfip_data, - 'seq_ssp', j.seq_ssp_data, - 'approved', j.approved_data, - 'contract', j.contract_data, - 'booking', j.booking_data, - 'q1', j.q1_data, - 'q2', j.q2_data, - 'q3', j.q3_data, - 'q4', j.q4_data, - 'totals', j.totals_data - ) AS data - FROM v3.v_form2_sheet_jsonb(p_form_id, p_sheet, p_sections, p_focus_lines) j - ORDER BY j._sort_rank; - RETURN; - END IF; - - - - - - - - - - - - - IF p_sheet = 'AHR_LIMIT' THEN - RETURN QUERY - WITH RECURSIVE tree AS ( - SELECT id AS root_id, id AS desc_id FROM v3.limit_template - UNION - SELECT t.root_id, child.id - FROM tree t - JOIN v3.limit_template child ON child.parent_id = t.desc_id - ), - leaf_amt AS ( - - SELECT lt.id, - fl.qty_q1, fl.qty_q2, fl.qty_q3, fl.qty_q4, - v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q1)AS amount_q1, - v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q2)AS amount_q2, - v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q3)AS amount_q3, - v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q4)AS amount_q4 - FROM v3.limit_template lt - LEFT JOIN v3.form_limit fl - ON fl.template_id = lt.id AND fl.budget_form_id = p_form_id - WHERE lt.row_type = 'LEAF' - ), - agg AS ( - SELECT t.root_id, - SUM(la.qty_q1) AS qty_q1, SUM(la.amount_q1) AS amount_q1, - SUM(la.qty_q2) AS qty_q2, SUM(la.amount_q2) AS amount_q2, - SUM(la.qty_q3) AS qty_q3, SUM(la.amount_q3) AS amount_q3, - SUM(la.qty_q4) AS qty_q4, SUM(la.amount_q4) AS amount_q4 - FROM tree t - JOIN leaf_amt la ON la.id = t.desc_id - GROUP BY t.root_id - ) - SELECT - - - CASE lt.row_type WHEN 'SECTION' THEN 'ROOT' - WHEN 'GROUP' THEN 'GROUP' - WHEN 'LEAF' THEN 'INPUT' END::VARCHAR, - CASE lt.row_type WHEN 'SECTION' THEN 0 WHEN 'GROUP' THEN 1 ELSE 2 END, - lt.sort_order::BIGINT, - jsonb_build_object( - 'id', lt.id, - 'section_no', lt.section_no, - 'expense_item_code',lt.expense_item_code, - 'name', lt.name, - 'unit', lt.unit, - 'limit_with_vat', lt.limit_with_vat, - 'limit_without_vat',lt.limit_without_vat, - 'qty_q1', a.qty_q1, 'amount_q1', a.amount_q1, - 'qty_q2', a.qty_q2, 'amount_q2', a.amount_q2, - 'qty_q3', a.qty_q3, 'amount_q3', a.amount_q3, - 'qty_q4', a.qty_q4, 'amount_q4', a.amount_q4, - 'comment', fl.comment - ) - FROM v3.limit_template lt - LEFT JOIN agg a ON a.root_id = lt.id - LEFT JOIN v3.form_limit fl - ON fl.template_id = lt.id AND fl.budget_form_id = p_form_id - WHERE p_focus_lines IS NULL - OR lt.id = ANY(v3._limit_template_path_set(p_focus_lines)) - ORDER BY lt.sort_order; - RETURN; - END IF; - - - IF p_sheet = 'AHR_RENT' THEN - RETURN QUERY - SELECT - 'INPUT'::VARCHAR, - 0, - sk._rn AS sort_order, - jsonb_build_object( - 'id', rd.id, - 'line_id', rd.line_id, - 'vsp_id', rd.vsp_id, - 'address', v.address, - 'object_type', v.format, - 'rented_area', v.total_area, - 'contract_number', rd.contract_number, - 'contract_end_date',rd.contract_end_date, - 'plan', jsonb_build_object('q1', rd.plan_q1, 'q2', rd.plan_q2, 'q3', rd.plan_q3, 'q4', rd.plan_q4, - 'year', COALESCE(rd.plan_q1,0)+COALESCE(rd.plan_q2,0)+COALESCE(rd.plan_q3,0)+COALESCE(rd.plan_q4,0)), - 'fact_q1', jsonb_build_object('jan', rd.actual_jan, 'feb', rd.actual_feb, 'mar', rd.actual_mar, - 'total', COALESCE(rd.actual_jan,0)+COALESCE(rd.actual_feb,0)+COALESCE(rd.actual_mar,0)), - 'fact_q2', jsonb_build_object('apr', rd.actual_apr, 'may', rd.actual_may, 'jun', rd.actual_jun, - 'total', COALESCE(rd.actual_apr,0)+COALESCE(rd.actual_may,0)+COALESCE(rd.actual_jun,0)), - 'fact_q3', jsonb_build_object('jul', rd.actual_jul, 'aug', rd.actual_aug, 'sep', rd.actual_sep, - 'total', COALESCE(rd.actual_jul,0)+COALESCE(rd.actual_aug,0)+COALESCE(rd.actual_sep,0)), - 'fact_q4', jsonb_build_object('oct', rd.actual_oct, 'nov', rd.actual_nov, 'dec', rd.actual_dec, - 'total', COALESCE(rd.actual_oct,0)+COALESCE(rd.actual_nov,0)+COALESCE(rd.actual_dec,0)), - 'comment', rd.comment - ) - FROM ( - SELECT rds.id, ROW_NUMBER() OVER (ORDER BY rds.id) AS _rn - FROM v3.rent_detail rds - JOIN v3.budget_line bl ON bl.id = rds.line_id - JOIN v3.vsp vs ON vs.id = rds.vsp_id - WHERE bl.budget_form_id = p_form_id - ) sk - JOIN v3.rent_detail rd ON rd.id = sk.id - JOIN v3.vsp v ON v.id = rd.vsp_id - WHERE p_focus_lines IS NULL OR rd.id = ANY(p_focus_lines) - ORDER BY sk._rn; - RETURN; - END IF; - - - IF p_sheet = 'AHR_UTILITY' THEN - RETURN QUERY - SELECT - 'INPUT'::VARCHAR, - 0, - sk._rn AS sort_order, - jsonb_build_object( - 'id', ud.id, - 'line_id', ud.line_id, - 'vsp_id', ud.vsp_id, - 'address', v.address, - 'object_type', v.format, - 'object_area', v.total_area, - 'contract_number', ud.contract_number, - 'contract_end_date',ud.contract_end_date, - 'plan', jsonb_build_object('q1', ud.plan_q1, 'q2', ud.plan_q2, 'q3', ud.plan_q3, 'q4', ud.plan_q4, - 'year', COALESCE(ud.plan_q1,0)+COALESCE(ud.plan_q2,0)+COALESCE(ud.plan_q3,0)+COALESCE(ud.plan_q4,0)), - 'fact_q1', jsonb_build_object('jan', ud.actual_jan, 'feb', ud.actual_feb, 'mar', ud.actual_mar, - 'total', COALESCE(ud.actual_jan,0)+COALESCE(ud.actual_feb,0)+COALESCE(ud.actual_mar,0)), - 'fact_q2', jsonb_build_object('apr', ud.actual_apr, 'may', ud.actual_may, 'jun', ud.actual_jun, - 'total', COALESCE(ud.actual_apr,0)+COALESCE(ud.actual_may,0)+COALESCE(ud.actual_jun,0)), - 'fact_q3', jsonb_build_object('jul', ud.actual_jul, 'aug', ud.actual_aug, 'sep', ud.actual_sep, - 'total', COALESCE(ud.actual_jul,0)+COALESCE(ud.actual_aug,0)+COALESCE(ud.actual_sep,0)), - 'fact_q4', jsonb_build_object('oct', ud.actual_oct, 'nov', ud.actual_nov, 'dec', ud.actual_dec, - 'total', COALESCE(ud.actual_oct,0)+COALESCE(ud.actual_nov,0)+COALESCE(ud.actual_dec,0)), - 'comment', ud.comment - ) - FROM ( - SELECT uds.id, ROW_NUMBER() OVER (ORDER BY uds.id) AS _rn - FROM v3.utility_detail uds - JOIN v3.budget_line bl ON bl.id = uds.line_id - JOIN v3.vsp vs ON vs.id = uds.vsp_id - WHERE bl.budget_form_id = p_form_id - ) sk - JOIN v3.utility_detail ud ON ud.id = sk.id - JOIN v3.vsp v ON v.id = ud.vsp_id - WHERE p_focus_lines IS NULL OR ud.id = ANY(p_focus_lines) - ORDER BY sk._rn; - RETURN; - END IF; - - - IF p_sheet = 'AHR_SECURITY' THEN - RETURN QUERY - SELECT - 'INPUT'::VARCHAR, - 0, - sk._rn AS sort_order, - jsonb_build_object( - 'id', sd.id, - 'line_id', sd.line_id, - 'vsp_id', sd.vsp_id, - 'address', v.address, - 'object_type', v.format, - 'object_area', v.total_area, - 'contract_number', sd.contract_number, - 'contract_end_date',sd.contract_end_date, - 'plan', jsonb_build_object('q1', sd.plan_q1, 'q2', sd.plan_q2, 'q3', sd.plan_q3, 'q4', sd.plan_q4, - 'year', COALESCE(sd.plan_q1,0)+COALESCE(sd.plan_q2,0)+COALESCE(sd.plan_q3,0)+COALESCE(sd.plan_q4,0)), - 'fact_q1', jsonb_build_object('jan', sd.actual_jan, 'feb', sd.actual_feb, 'mar', sd.actual_mar, - 'total', COALESCE(sd.actual_jan,0)+COALESCE(sd.actual_feb,0)+COALESCE(sd.actual_mar,0)), - 'fact_q2', jsonb_build_object('apr', sd.actual_apr, 'may', sd.actual_may, 'jun', sd.actual_jun, - 'total', COALESCE(sd.actual_apr,0)+COALESCE(sd.actual_may,0)+COALESCE(sd.actual_jun,0)), - 'fact_q3', jsonb_build_object('jul', sd.actual_jul, 'aug', sd.actual_aug, 'sep', sd.actual_sep, - 'total', COALESCE(sd.actual_jul,0)+COALESCE(sd.actual_aug,0)+COALESCE(sd.actual_sep,0)), - 'fact_q4', jsonb_build_object('oct', sd.actual_oct, 'nov', sd.actual_nov, 'dec', sd.actual_dec, - 'total', COALESCE(sd.actual_oct,0)+COALESCE(sd.actual_nov,0)+COALESCE(sd.actual_dec,0)), - 'comment', sd.comment - ) - FROM ( - SELECT sds.id, ROW_NUMBER() OVER (ORDER BY sds.id) AS _rn - FROM v3.security_detail sds - JOIN v3.budget_line bl ON bl.id = sds.line_id - JOIN v3.vsp vs ON vs.id = sds.vsp_id - WHERE bl.budget_form_id = p_form_id - ) sk - JOIN v3.security_detail sd ON sd.id = sk.id - JOIN v3.vsp v ON v.id = sd.vsp_id - WHERE p_focus_lines IS NULL OR sd.id = ANY(p_focus_lines) - ORDER BY sk._rn; - RETURN; - END IF; - - - - - - - - - - IF p_sheet = 'OTCH9F' THEN - RETURN QUERY - WITH base AS ( - SELECT far.id, far.budget_form_id, far.expense_item_id, - far.equipment_name, far.month, - far.acquired_qty_604, far.acquired_amt_604, - far.disposed_qty_604, far.disposed_amt_604, - far.acquired_qty_60415, far.acquired_amt_60415, - far.transferred_qty_60415, far.transferred_amt_60415, - far.go_balance_only_amt, - - FIRST_VALUE(COALESCE(far.opening_qty_604,0)) - OVER w AS base_qty_604, - FIRST_VALUE(COALESCE(far.opening_amt_604,0)) - OVER w AS base_amt_604, - FIRST_VALUE(COALESCE(far.opening_qty_60415,0)) - OVER w AS base_qty_60415, - FIRST_VALUE(COALESCE(far.opening_amt_60415,0)) - OVER w AS base_amt_60415, - - COALESCE(SUM(COALESCE(far.acquired_qty_604,0) - COALESCE(far.disposed_qty_604,0)) - OVER w_prev, 0) AS cum_dq_604, - COALESCE(SUM(COALESCE(far.acquired_amt_604,0) - COALESCE(far.disposed_amt_604,0)) - OVER w_prev, 0) AS cum_da_604, - COALESCE(SUM(COALESCE(far.acquired_qty_60415,0) - COALESCE(far.transferred_qty_60415,0)) - OVER w_prev, 0) AS cum_dq_60415, - COALESCE(SUM(COALESCE(far.acquired_amt_60415,0) - COALESCE(far.transferred_amt_60415,0)) - OVER w_prev, 0) AS cum_da_60415 - FROM v3.fixed_asset_report far - WHERE far.budget_form_id = p_form_id - AND (p_focus_lines IS NULL OR EXISTS ( - SELECT 1 FROM v3.fixed_asset_report ff - WHERE ff.id = ANY(p_focus_lines) - AND ff.expense_item_id IS NOT DISTINCT FROM far.expense_item_id - AND ff.equipment_name IS NOT DISTINCT FROM far.equipment_name)) - WINDOW w AS (PARTITION BY far.budget_form_id, far.expense_item_id, far.equipment_name - ORDER BY far.month), - w_prev AS (PARTITION BY far.budget_form_id, far.expense_item_id, far.equipment_name - ORDER BY far.month - ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) - ), - eff AS ( - SELECT b.*, - (b.base_qty_604 + b.cum_dq_604) AS opening_qty_604_eff, - (b.base_amt_604 + b.cum_da_604) AS opening_amt_604_eff, - (b.base_qty_60415 + b.cum_dq_60415) AS opening_qty_60415_eff, - (b.base_amt_60415 + b.cum_da_60415) AS opening_amt_60415_eff - FROM base b - ) - SELECT - 'INPUT'::VARCHAR, - 0, - sk._rn AS sort_order, - jsonb_build_object( - 'id', eff.id, - 'expense_item_id', ei.id, - 'item_id', ei.item_id, - 'section_code', ei.section_code, - 'equipment_name', eff.equipment_name, - 'month', eff.month, - 'b_604', jsonb_build_object( - 'opening_qty', eff.opening_qty_604_eff, - 'opening_amt', eff.opening_amt_604_eff, - 'acquired_qty', eff.acquired_qty_604, - 'acquired_amt', eff.acquired_amt_604, - 'disposed_qty', eff.disposed_qty_604, - 'disposed_amt', eff.disposed_amt_604 - ), - 'b_60415', jsonb_build_object( - 'opening_qty', eff.opening_qty_60415_eff, - 'opening_amt', eff.opening_amt_60415_eff, - 'acquired_qty', eff.acquired_qty_60415, - 'acquired_amt', eff.acquired_amt_60415, - 'transferred_qty',eff.transferred_qty_60415, - 'transferred_amt',eff.transferred_amt_60415 - ), - 'totals', jsonb_build_object( - - 'acquired_total', COALESCE(eff.acquired_amt_604,0)+COALESCE(eff.acquired_amt_60415,0) - +COALESCE(eff.go_balance_only_amt,0)-COALESCE(eff.transferred_amt_60415,0), - 'go_balance_only',eff.go_balance_only_amt, - - 'disposed_total', COALESCE(eff.disposed_amt_604,0), - - 'balance_qty', (eff.opening_qty_604_eff + COALESCE(eff.acquired_qty_604,0) - COALESCE(eff.disposed_qty_604,0)) - + (eff.opening_qty_60415_eff + COALESCE(eff.acquired_qty_60415,0) - COALESCE(eff.transferred_qty_60415,0)), - 'balance_amt', (eff.opening_amt_604_eff + COALESCE(eff.acquired_amt_604,0) - COALESCE(eff.disposed_amt_604,0)) - + (eff.opening_amt_60415_eff + COALESCE(eff.acquired_amt_60415,0) - COALESCE(eff.transferred_amt_60415,0)) - ) - ) - FROM eff - JOIN v3.expense_item ei ON ei.id = eff.expense_item_id - JOIN ( - SELECT fs.id, - ROW_NUMBER() OVER (ORDER BY fs.expense_item_id, fs.month, fs.id) AS _rn - FROM v3.fixed_asset_report fs - JOIN v3.expense_item eis ON eis.id = fs.expense_item_id - WHERE fs.budget_form_id = p_form_id - ) sk ON sk.id = eff.id - ORDER BY sk._rn; - RETURN; - END IF; - - - IF p_sheet = 'SMETA' THEN - RETURN QUERY - SELECT - sm.row_type, - sm.depth, - ROW_NUMBER() OVER (ORDER BY sm.section_code) AS sort_order, - jsonb_build_object( - 'section_code', sm.section_code, - 'name', sm.name, - 'plan', jsonb_build_object( - 'support', jsonb_build_object('q1', sm.plan_supp_q1, 'q2', sm.plan_supp_q2, 'q3', sm.plan_supp_q3, 'q4', sm.plan_supp_q4, 'year', sm.plan_supp_year), - 'development', jsonb_build_object('q1', sm.plan_dev_q1, 'q2', sm.plan_dev_q2, 'q3', sm.plan_dev_q3, 'q4', sm.plan_dev_q4, 'year', sm.plan_dev_year) - ), - 'approved', jsonb_build_object( - 'support', jsonb_build_object('q1', sm.appr_supp_q1, 'q2', sm.appr_supp_q2, 'q3', sm.appr_supp_q3, 'q4', sm.appr_supp_q4, 'year', sm.appr_supp_year), - 'development', jsonb_build_object('q1', sm.appr_dev_q1, 'q2', sm.appr_dev_q2, 'q3', sm.appr_dev_q3, 'q4', sm.appr_dev_q4, 'year', sm.appr_dev_year) - ), - 'fact', jsonb_build_object( - 'support', jsonb_build_object('q1', sm.fact_supp_q1, 'q2', sm.fact_supp_q2, 'q3', sm.fact_supp_q3, 'q4', sm.fact_supp_q4, 'year', sm.fact_supp_year), - 'development', jsonb_build_object('q1', sm.fact_dev_q1, 'q2', sm.fact_dev_q2, 'q3', sm.fact_dev_q3, 'q4', sm.fact_dev_q4, 'year', sm.fact_dev_year) - ), - - - 'corrected', jsonb_build_object( - 'support', jsonb_build_object('q2', sm.corr_supp_q2, 'q3', sm.corr_supp_q3, 'q4', sm.corr_supp_q4), - 'development', jsonb_build_object('q2', sm.corr_dev_q2, 'q3', sm.corr_dev_q3, 'q4', sm.corr_dev_q4) - ) - ) - FROM v3.v_form2_smeta(p_form_id) sm - ORDER BY sm.section_code; - RETURN; - END IF; - - RAISE EXCEPTION 'Unknown sheet: %', p_sheet - USING HINT = 'Use AHR / CAP / OPER / AHR_LIMIT / AHR_RENT / AHR_UTILITY / AHR_SECURITY / OTCH9F / SMETA'; - -END; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.v_form1_view(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_direction character varying DEFAULT NULL::character varying, p_focus_lines integer[] DEFAULT NULL::integer[]) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE plpgsql - STABLE -AS $function$ -BEGIN - IF p_sheet NOT IN ('AHR','CAP','OPER') THEN - RAISE EXCEPTION 'v_form1_view: unsupported sheet %', p_sheet; - END IF; - - RETURN QUERY - SELECT - j.row_type, - j.depth, - j._sort_rank AS sort_order, - jsonb_build_object( - 'line_id', j.line_id, - 'header', j.header, - 'plan', j.plan_data, - 'contract_summary', j.contract_summary, - 'allocation', j.allocation_data, - 'sequestration', j.sequestration_data, - 'reserve', j.reserve_data, - 'approved', j.approved_data, - 'collegial', j.collegial_data, - 'ckk', j.ckk_data, - 'contract_detail', j.contract_detail, - 'q1', j.q1_data, - 'q2', j.q2_data, - 'q3', j.q3_data, - 'q4', j.q4_data, - 'totals', j.totals_data - ) AS data - FROM v3.v_form1_sheet_jsonb(p_form_id, p_sheet, p_direction, p_sections, p_focus_lines) j - ORDER BY j._sort_rank; - RETURN; -END; -$function$ -; - -CREATE OR REPLACE FUNCTION v3.v_form_view(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[], p_direction character varying DEFAULT NULL::character varying, p_user_id integer DEFAULT NULL::integer) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE plpgsql - STABLE -AS $function$ -DECLARE - v_form_type VARCHAR; - v_year INT; - v_org_unit_id INT; - v_user_id INT; -BEGIN - SELECT form_type_code, year, org_unit_id - INTO v_form_type, v_year, v_org_unit_id - FROM v3.budget_form - WHERE id = p_form_id; - - IF NOT FOUND THEN - RAISE EXCEPTION 'budget_form id=% не существует в v3.budget_form', p_form_id; - END IF; - - v_user_id := p_user_id; - IF p_user_id IS NULL THEN - v_user_id := v3.current_user_id(); - END IF; - RETURN QUERY - SELECT - 'META'::VARCHAR, - -1, - 0::BIGINT, - jsonb_build_object( - 'user_id', v_user_id, - 'role', v3.user_role_code(v_user_id), - 'sheet', p_sheet, - 'editable', COALESCE( - (SELECT jsonb_agg( - jsonb_build_object('column', ec.column_key, - 'closes_at', ec.closes_at) - ORDER BY ec.column_key) - FROM v3.editable_columns_for(p_form_id, v_user_id, p_sheet, p_direction) ec), - '[]'::JSONB) - ); - - IF v_form_type = 'FORM_1' THEN - - IF p_sheet = 'SMETA' THEN - RETURN QUERY - SELECT - sm.row_type, - sm.depth, - ROW_NUMBER() OVER (ORDER BY sm.section_code) AS sort_order, - jsonb_build_object( - 'section_code', sm.section_code, - 'name', sm.name, - 'plan', jsonb_build_object( - 'support', jsonb_build_object('q1', sm.supp_plan_q1, 'q2', sm.supp_plan_q2, - 'q3', sm.supp_plan_q3, 'q4', sm.supp_plan_q4, - 'year', sm.supp_plan_year), - 'development', jsonb_build_object('q1', sm.dev_plan_q1, 'q2', sm.dev_plan_q2, - 'q3', sm.dev_plan_q3, 'q4', sm.dev_plan_q4, - 'year', sm.dev_plan_year), - 'total_year', sm.total_plan_year), - 'approved', jsonb_build_object( - 'support', jsonb_build_object('q1', sm.supp_appr_q1, 'q2', sm.supp_appr_q2, - 'q3', sm.supp_appr_q3, 'q4', sm.supp_appr_q4, - 'year', sm.supp_appr_year), - 'development', jsonb_build_object('q1', sm.dev_appr_q1, 'q2', sm.dev_appr_q2, - 'q3', sm.dev_appr_q3, 'q4', sm.dev_appr_q4, - 'year', sm.dev_appr_year), - 'total_year', sm.total_appr_year), - 'fact', jsonb_build_object( - 'support', jsonb_build_object('q1', sm.supp_act_q1, 'q2', sm.supp_act_q2, - 'q3', sm.supp_act_q3, 'q4', sm.supp_act_q4, - 'year', sm.supp_act_year), - 'development', jsonb_build_object('q1', sm.dev_act_q1, 'q2', sm.dev_act_q2, - 'q3', sm.dev_act_q3, 'q4', sm.dev_act_q4, - 'year', sm.dev_act_year), - 'total_year', sm.total_act_year), - 'corrected', jsonb_build_object( - 'support', jsonb_build_object('q2', sm.supp_corr_q2, 'q3', sm.supp_corr_q3, 'q4', sm.supp_corr_q4), - 'development', jsonb_build_object('q2', sm.dev_corr_q2, 'q3', sm.dev_corr_q3, 'q4', sm.dev_corr_q4)) - ) - FROM v3.v_form1_smeta(v_year, v_org_unit_id) sm - ORDER BY sm.section_code; - RETURN; - END IF; - - IF p_sheet IN ('AHR','CAP','OPER') THEN - RETURN QUERY SELECT * FROM v3.v_form1_view(p_form_id, p_sheet, p_sections, p_direction, NULL); - RETURN; - END IF; - - RAISE EXCEPTION 'Unknown FORM_1 sheet: %', p_sheet - USING HINT = 'Use AHR / CAP / OPER / SMETA'; - END IF; - - IF v_form_type = 'FORM_2' THEN - RETURN QUERY SELECT * FROM v3.v_form2_view(p_form_id, p_sheet, p_sections); - RETURN; - END IF; - - IF v_form_type = 'FORM_4' THEN - RETURN QUERY SELECT * FROM v3.v_form4_view(p_form_id, p_sheet, p_sections); - RETURN; - END IF; - - RAISE EXCEPTION 'Unsupported form_type=% for form_id=%', v_form_type, p_form_id; - -END; -$function$ -; - -CREATE OR REPLACE FUNCTION v3._form_affected_rows(p_form_id integer, p_sheet character varying, p_ids integer[], p_direction character varying DEFAULT NULL::character varying, p_sections text[] DEFAULT NULL::text[]) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE plpgsql - STABLE - SET jit TO 'off' -AS $function$ -DECLARE - v_form_type VARCHAR; - v_strip TEXT[] := ARRAY[]::TEXT[]; - v_lc_path INT[]; - v_eid_set INT[]; - v_ei_path INT[]; -BEGIN - SELECT bf.form_type_code INTO v_form_type - FROM v3.budget_form bf - WHERE bf.id = p_form_id; - - IF p_sections IS NOT NULL THEN - SELECT COALESCE(array_agg(k), ARRAY[]::TEXT[]) - INTO v_strip - FROM unnest(ARRAY['plan','seq_dfip','seq_ssp','approved','contract','booking', - 'contract_summary','allocation','collegial','ckk', - 'sequestration','reserve','contract_detail', - 'q1','q2','q3','q4','totals', - 'fact_q1','fact_q2','fact_q3','fact_q4']) AS k - WHERE NOT (k = ANY(p_sections)); - END IF; - - IF v_form_type = 'FORM_1' AND p_sheet IN ('AHR','CAP','OPER') THEN - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form1_view(p_form_id, p_sheet, p_sections, p_direction, COALESCE(p_ids, '{}'::INT[])) v - ORDER BY v.sort_order; - RETURN; - ELSIF v_form_type = 'FORM_2' AND p_sheet IN ('AHR','CAP','OPER','AHR_RENT','AHR_UTILITY','AHR_SECURITY','AHR_LIMIT','OTCH9F') THEN - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form2_view(p_form_id, p_sheet, p_sections, COALESCE(p_ids, '{}'::INT[])) v - ORDER BY v.sort_order; - RETURN; - END IF; - - IF p_sheet IN ('AHR_RENT','AHR_UTILITY','AHR_SECURITY') THEN - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE v.row_type = 'INPUT' AND (v.data->>'id')::INT = ANY(p_ids) - ORDER BY v.sort_order; - - ELSIF p_sheet = 'AHR_LIMIT' THEN - v_lc_path := v3._limit_template_path_set(p_ids); - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE (v.data->>'id')::INT = ANY(v_lc_path) - ORDER BY v.sort_order; - - ELSIF p_sheet = 'OTCH9F' THEN - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE EXISTS ( - SELECT 1 FROM v3.fixed_asset_report far - WHERE far.id = ANY(p_ids) - AND far.expense_item_id = (v.data->>'expense_item_id')::INT - AND far.equipment_name IS NOT DISTINCT FROM (v.data->>'equipment_name')) - ORDER BY v.sort_order; - - ELSE - SELECT array_agg(DISTINCT bl.expense_item_id) - INTO v_eid_set - FROM v3.budget_line bl - WHERE bl.id = ANY(p_ids); - v_ei_path := v3._expense_item_path_set(v_eid_set); - - IF v_form_type = 'FORM_4' THEN - RETURN QUERY - WITH vv AS MATERIALIZED ( - SELECT f.row_type, f.depth, f.sort_order, f.data - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) f - WHERE f.row_type <> 'META' - ), - chg AS ( - SELECT DISTINCT (x.data->'header'->>'program_id')::INT AS program_id, - (x.data->'header'->>'project_id')::INT AS project_id - FROM vv x - WHERE x.row_type = 'INPUT' AND (x.data->>'line_id')::INT = ANY(p_ids) - ) - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM vv v - WHERE (v.row_type = 'INPUT' AND (v.data->>'line_id')::INT = ANY(p_ids)) - OR (v.row_type = 'ROOT' - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) - OR (v.row_type = 'GROUP' - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) - AND (v.data->'header'->>'program_id')::INT IN (SELECT c.program_id FROM chg c)) - OR (v.row_type = 'ITEM' - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path) - AND (v.data->'header'->>'project_id')::INT IN (SELECT c.project_id FROM chg c)) - ORDER BY v.sort_order; - ELSE - RETURN QUERY - SELECT v.row_type, v.depth, v.sort_order, v.data - v_strip - FROM v3.v_form_view(p_form_id, p_sheet, p_sections, p_direction) v - WHERE (v.row_type IN ('ROOT','GROUP','ITEM','SUB_ITEM','SUB_SUB_ITEM') - AND (v.data->'header'->>'expense_item_id')::INT = ANY(v_ei_path)) - OR (v.row_type = 'INPUT' - AND (v.data->>'line_id')::INT = ANY(p_ids)) - ORDER BY v.sort_order; - END IF; - END IF; -END; -$function$ -; - - -CREATE OR REPLACE FUNCTION v3.get_form2_ahr_satellite_delta(p_form_id integer, p_source_sheet character varying, p_source_row_id integer) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE sql - STABLE - SET jit TO 'off' -AS $function$ - WITH target_lines AS ( - SELECT m.target_line_id AS line_id - FROM v3.form2_ahr_satellite_line_source m - JOIN v3.budget_line bl ON bl.id = m.target_line_id - WHERE m.source_sheet = p_source_sheet - AND m.source_id = p_source_row_id - AND bl.budget_form_id = p_form_id - AND p_source_sheet IN ('AHR_RENT', 'AHR_UTILITY', 'AHR_SECURITY') - - UNION - - SELECT bl.id AS line_id - FROM v3.limit_template lt - JOIN v3.expense_item ei - ON ei.sheet = 'AHR' - AND ei.direction = 'Support' - AND ( - (ei.depth = 3 AND ei.item_id = lt.expense_item_code) - OR ei.num_group_id = lt.expense_item_code - ) - JOIN v3.budget_line bl - ON bl.budget_form_id = p_form_id - AND bl.expense_item_id = ei.id - AND bl.name = regexp_replace( - lt.name, - '^[[:space:]]*-[[:space:]]*', - '' - ) - WHERE p_source_sheet = 'AHR_LIMIT' - AND lt.id = p_source_row_id - AND lt.row_type = 'LEAF' - ) - SELECT r.row_type, r.depth, r.sort_order, r.data - FROM v3._form_affected_rows( - p_form_id, 'AHR', - COALESCE((SELECT array_agg(tl.line_id) FROM target_lines tl), '{}'), - 'Support', NULL) r - ORDER BY r.sort_order; -$function$ -; diff --git a/api/alembic/versions/sql/0053_form2_ahr_source_sheet.sql b/api/alembic/versions/sql/0053_form2_ahr_source_sheet.sql index 8ce866f..62f2218 100644 --- a/api/alembic/versions/sql/0053_form2_ahr_source_sheet.sql +++ b/api/alembic/versions/sql/0053_form2_ahr_source_sheet.sql @@ -823,3 +823,609 @@ AS $function$ ORDER BY s._sort_path; $function$ ; + + + +-- AURORA-1846: FORM_4, замена рекурсивного агрегата v3.jsonb_sum в +-- v3.v_form4_sheet_jsonb на разворот листьев jsonb + GROUPING SETS. +-- Тело — копия sql/0012_del_project.sql:1091-1617, изменён только блок +-- «4. Агрегаты». v3.jsonb_sum / v3.jsonb_numeric_sum не удаляются (эталон в тестах). + +CREATE OR REPLACE FUNCTION v3.v_form4_sheet_jsonb(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[]) + RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) + LANGUAGE sql + STABLE + SET jit TO 'off' -- оценка плана выше порога JIT, компиляция дороже выполнения (AURORA-1846) +AS $function$ + -- ═══ 1. Базовые INPUT-строки с расширенной иерархией ═══════════════════════ + WITH inp_raw AS ( + SELECT j.* + FROM v3.v_form4_sheet_lines_jsonb(p_form_id, p_sheet, p_sections) j + WHERE j.row_type = 'INPUT' + ), + inp AS ( + SELECT + i.*, + bl.project_id AS line_project_id, + + -- --- разрешение проекта --- + -- A. bl.project_id → project (level='project') + -- B. bl.project_id → program (level='program') — тогда проекта нет + CASE WHEN prj.id IS NOT NULL THEN prj.id END AS prj_id, + CASE WHEN prj.id IS NOT NULL THEN prj.name END AS prj_name, + + -- --- разрешение программы --- + -- A. через проект: prog_via_prj + -- B. напрямую: prog_direct + COALESCE(prog_via_prj.id, prog_direct.id) AS prog_id, + COALESCE(prog_via_prj.name, prog_direct.name) AS prog_name, + + -- --- section (depth=0) --- + sec.id AS sec_id, + sec.section_code AS sec_code, + sec.name AS sec_name + + FROM inp_raw i + JOIN v3.budget_line bl ON bl.id = i.line_id + + -- проект (level='project') + LEFT JOIN v3.form4_project prj + ON prj.id = bl.project_id AND prj.level = 'project' + + -- программа через проект + LEFT JOIN v3.form4_project prog_via_prj + ON prog_via_prj.id = prj.parent_id AND prog_via_prj.level = 'program' + + -- программа напрямую (bl.project_id → program) + LEFT JOIN v3.form4_project prog_direct + ON prog_direct.id = bl.project_id AND prog_direct.level = 'program' + + -- раздел depth=0 (через expense_item) + JOIN v3.expense_item ei ON ei.id = bl.expense_item_id + LEFT JOIN LATERAL ( + WITH RECURSIVE up AS ( + SELECT id, parent_id, name, section_code, depth + FROM v3.expense_item WHERE id = ei.id + UNION ALL + SELECT e.id, e.parent_id, e.name, e.section_code, e.depth + FROM v3.expense_item e JOIN up u ON u.parent_id = e.id + ) + SELECT id, name, section_code FROM up WHERE depth = 0 LIMIT 1 + ) sec ON TRUE + ), + tp_agg AS ( + SELECT 1 AS tp_id, + jsonb_build_object( + 'q1', 0, 'q2', 0, + 'q3', 0, 'q4', 0, + 'year', 0, 'comment', null + ) AS tp_plan, + + + + jsonb_build_object( + 'q1', 0, 'q2', 0, + 'q3', 0, 'q4', 0, + 'year', 0, + 'justification', null + ) AS tp_seq_dfip, + + jsonb_build_object( + 'q1', 0, 'q2', 0, + 'q3', 0, 'q4', 0, + 'year', 0 + ) AS tp_approved, + + jsonb_build_object( + 'total', null, + 'reference', null, + 'counterparty', null, + 'deadline', null, + 'comment', null, + 'future_y1', null, + 'future_y2', null, + 'other_ssp', null, + 'centralized_flag', null + ) AS tp_contract_summary, + + jsonb_build_object( + 'contract_ref', null, + 'allocation_purpose', null + ) AS tp_allocation, + + jsonb_build_object( + 'q1', 0, 'q2', 0, + 'q3', 0, 'q4', 0, + 'year', 0, + 'justification', null + ) AS tp_reserve, + + jsonb_build_object( + 'approved', null, + 'protocol', null, + 'note', null + ) AS tp_collegial, + + jsonb_build_object( + 'ceiling', null, + 'q1', null, + 'q2', null, + 'q3', null, + 'q4', null, + 'rf_schedule', null, + 'delivery_deadline', null, + 'proc_plan', null, + 'proc_method', null, + 'comment', null + ) AS tp_ckk, + + jsonb_build_object( + 'act', null, + 'date', null, + 'scheme', null, + 'addenda', null, + 'ceiling', null, + 'comment', null, + 'subject', null, + 'currency', null, + 'deadline', null, + 'vat_rate', null, + 'reference', null, + 'q1', null, + 'q2', null, + 'q3', null, + 'q4', null, + 'rf_schedule', null, + 'counterparty', null, + 'exchange_rate', null, + 'amount_foreign', null + ) AS tp_contract, + + jsonb_build_object( + 'y2026', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null), + 'y2027', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null) + ) AS tp_booking, + + jsonb_build_object( + 'total', 0, + 'adj_rf', null, + 'pay_ho', null, + 'pay_rf', null, + 'adj_ssp', null, + 'booking', null, + 'pay_act', null, + 'pay_date', null, + 'actual_m1', null, + 'actual_m2', null, + 'actual_m3', null, + 'pay_amount', null, + 'adj_comment', null, + 'adj_current', null, + 'adj_reserve', null, + 'pay_comment', null, + 'transfer_q2', null, + 'transfer_q3', null, + 'transfer_q4', null, + 'transfer_econ', null, + 'actual_quarter', 0, + 'corrected_plan', 0, + 'residual_after_actual', 0, + 'residual_after_booking', 0 + ) AS tp_q1, + + jsonb_build_object( + 'target_change', null, + 'base_correction', null, + 'base_correction_comment', null, + 'revision_inc', null, + 'revision_seq', null, + 'revision_comment', null, + 'new_plan', 0, + 'adj_current', null, + 'adj_ssp', null, + 'adj_rf', null, + 'adj_reserve', null, + 'adj_comment', null, + 'corrected_plan', 0, + 'pay_date', null, + 'pay_amount', null, + 'pay_ho', null, + 'pay_rf', null, + 'pay_comment', null, + 'pay_act', null, + 'booking', null, + 'actual_m1', null, + 'actual_m2', null, + 'actual_m3', null, + 'actual_quarter', 0, + 'residual_after_booking', 0, + 'residual_after_actual', 0, + 'transfer_q3', null, + 'transfer_q4', null, + 'transfer_econ', null, + 'total', 0 + ) AS tp_q2, + + jsonb_build_object( + 'target_change', null, + 'base_correction', null, + 'base_correction_comment', null, + 'revision_inc', null, + 'revision_seq', null, + 'revision_comment', null, + 'new_plan', 0, + 'adj_current', null, + 'adj_ssp', null, + 'adj_rf', null, + 'adj_reserve', null, + 'adj_comment', null, + 'corrected_plan', 0, + 'pay_date', null, + 'pay_amount', null, + 'pay_ho', null, + 'pay_rf', null, + 'pay_comment', null, + 'pay_act', null, + 'booking', null, + 'actual_m1', null, + 'actual_m2', null, + 'actual_m3', null, + 'actual_quarter', 0, + 'residual_after_booking', 0, + 'residual_after_actual', 0, + 'transfer_q4', null, + 'transfer_econ', null, + 'total', 0 + ) AS tp_q3, + + jsonb_build_object( + 'target_change', null, + 'base_correction', null, + 'base_correction_comment', null, + 'revision_inc', null, + 'revision_seq', null, + 'revision_comment', null, + 'new_plan', 0, + 'adj_current', null, + 'adj_ssp', null, + 'adj_rf', null, + 'adj_reserve', null, + 'adj_comment', null, + 'corrected_plan', 0, + 'pay_date', null, + 'pay_amount', null, + 'pay_ho', null, + 'pay_rf', null, + 'pay_comment', null, + 'pay_act', null, + 'booking', null, + 'actual_m1', null, + 'actual_m2', null, + 'actual_m3', null, + 'actual_spod', null, + 'actual_quarter', 0, + 'residual_after_booking', 0, + 'residual_after_actual', 0, + 'transfer_econ', null, + 'total', 0 + ) AS tp_q4, + jsonb_build_object( + 'fact_year', 0 + ) AS tp_totals + + + + + + ), + -- ═══ 2. Все программы (включая пустые) ═════════════════════════════════════ + all_programs AS ( + SELECT + fp.id AS prog_id, + fp.name AS prog_name, + fp.section_code, + sec.id AS sec_id, + sec.section_code AS sec_code, + sec.name AS sec_name + FROM v3.form4_project fp + LEFT JOIN LATERAL ( + SELECT id, section_code, name + FROM v3.expense_item + WHERE section_code = fp.section_code AND depth = 0 + LIMIT 1 + ) sec ON TRUE + WHERE fp.level = 'program' + AND (p_sections IS NULL OR fp.section_code = ANY(p_sections)) + AND (fp.section_code = p_sheet) AND fp.form_id = p_form_id + ), + + -- ═══ 3. Все проекты под программами (включая пустые) ═══════════════════════ + all_projects AS ( + SELECT + prj.id AS prj_id, + prj.name AS prj_name, + prj.parent_id AS prog_id, + ap.sec_id, ap.sec_code, ap.sec_name + FROM v3.form4_project prj + JOIN all_programs ap ON ap.prog_id = prj.parent_id + WHERE prj.level = 'project' AND (ap.section_code = p_sheet) + ), + + -- ═══ 4. Агрегаты с финансовыми данными (только из inp) ════════════════════ + -- Замена рекурсивного агрегата v3.jsonb_sum (AURORA-1846): листья jsonb + -- разворачиваются в строки, суммируются GROUPING SETS по трём уровням + -- (раздел / программа / проект) и собираются обратно в jsonb. + -- Правила те же, что у v3.jsonb_numeric_sum: числа складываются, нечисловые + -- игнорируются, если по пути есть число; текст/null сохраняются, если путь + -- встретился в группе один раз; иначе JSON null; NULL-секция даёт NULL. + + -- Имена групп (без jsonb) + prj_names AS ( + SELECT + sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name, + prog_id, MAX(prog_name) AS prog_name, + prj_id, MAX(prj_name) AS prj_name + FROM inp WHERE prj_id IS NOT NULL + GROUP BY sec_id, prog_id, prj_id + ), + prog_names AS ( + SELECT + sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name, + prog_id, MAX(prog_name) AS prog_name + FROM inp WHERE prog_id IS NOT NULL + GROUP BY sec_id, prog_id + ), + root_names AS ( + SELECT + sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name + FROM inp + GROUP BY sec_id + ), + + -- Листья jsonb: (колонка, ключ 1-го уровня, ключ 2-го уровня или NULL, значение) + leaves AS ( + SELECT + i.sec_id, i.prog_id, i.prj_id, + c.col, e1.key AS k1, e2.key AS k2, + COALESCE(e2.value, e1.value) AS val + FROM inp i + CROSS JOIN LATERAL (VALUES + ('plan', i.plan_data), + ('seq_dfip', i.seq_dfip_data), + ('approved', i.approved_data), + ('contract_summary', i.contract_summary_data), + ('allocation', i.allocation_data), + ('reserve', i.reserve_data), + ('collegial', i.collegial_data), + ('ckk', i.ckk_data), + ('contract', i.contract_data), + ('booking', i.booking_data), + ('q1', i.q1_data), + ('q2', i.q2_data), + ('q3', i.q3_data), + ('q4', i.q4_data), + ('totals', i.totals_data) + ) AS c(col, v) + CROSS JOIN LATERAL jsonb_each( + CASE WHEN jsonb_typeof(c.v) = 'object' THEN c.v END + ) AS e1 + LEFT JOIN LATERAL jsonb_each( + CASE WHEN jsonb_typeof(e1.value) = 'object' THEN e1.value END + ) AS e2 ON TRUE + ), + + -- Суммы листьев сразу по трём уровням (lvl: 3 раздел, 1 программа, 0 проект) + leaf_agg AS ( + SELECT + GROUPING(prog_id, prj_id) AS lvl, + sec_id, prog_id, prj_id, col, k1, k2, + COUNT(*) AS n, + COUNT(*) FILTER (WHERE jsonb_typeof(val) = 'number') AS n_num, + SUM((val #>> '{}')::numeric) FILTER (WHERE jsonb_typeof(val) = 'number') AS s, + (array_agg(val))[1] AS one + FROM leaves + GROUP BY GROUPING SETS ( + (sec_id, col, k1, k2), + (sec_id, prog_id, col, k1, k2), + (sec_id, prog_id, prj_id, col, k1, k2) + ) + ), + leaf_val AS ( + SELECT + lvl, sec_id, prog_id, prj_id, col, k1, k2, + CASE + WHEN n_num > 0 THEN to_jsonb(s) + WHEN n = 1 THEN one + ELSE 'null'::jsonb + END AS v + FROM leaf_agg + WHERE NOT (lvl = 1 AND prog_id IS NULL) + AND NOT (lvl = 0 AND prj_id IS NULL) + ), + -- Сборка второго уровня вложенности (booking.y2026.q1 → объект по ключу k1) + k1_val AS ( + SELECT + lvl, sec_id, prog_id, prj_id, col, k1, + CASE + WHEN bool_or(k2 IS NOT NULL) THEN jsonb_object_agg(k2, v) FILTER (WHERE k2 IS NOT NULL) + ELSE (array_agg(v))[1] + END AS v + FROM leaf_val + GROUP BY lvl, sec_id, prog_id, prj_id, col, k1 + ), + -- Сборка по колонкам: одна строка на группу + lvl_data AS ( + SELECT + lvl, sec_id, prog_id, prj_id, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'plan') AS plan_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'seq_dfip') AS seq_dfip_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'approved') AS approved_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'contract_summary') AS contract_summary_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'allocation') AS allocation_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'reserve') AS reserve_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'collegial') AS collegial_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'ckk') AS ckk_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'contract') AS contract_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'booking') AS booking_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'q1') AS q1_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'q2') AS q2_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'q3') AS q3_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'q4') AS q4_data, + jsonb_object_agg(k1, v) FILTER (WHERE col = 'totals') AS totals_data + FROM k1_val + GROUP BY lvl, sec_id, prog_id, prj_id + ), + + prj_agg AS ( + SELECT n.*, d.plan_data, d.seq_dfip_data, d.approved_data, d.contract_summary_data, d.allocation_data, d.reserve_data, d.collegial_data, d.ckk_data, d.contract_data, d.booking_data, d.q1_data, d.q2_data, d.q3_data, d.q4_data, d.totals_data + FROM prj_names n + LEFT JOIN lvl_data d + ON d.lvl = 0 AND d.sec_id = n.sec_id AND d.prog_id = n.prog_id AND d.prj_id = n.prj_id + ), + prog_agg AS ( + SELECT n.*, d.plan_data, d.seq_dfip_data, d.approved_data, d.contract_summary_data, d.allocation_data, d.reserve_data, d.collegial_data, d.ckk_data, d.contract_data, d.booking_data, d.q1_data, d.q2_data, d.q3_data, d.q4_data, d.totals_data + FROM prog_names n + LEFT JOIN lvl_data d + ON d.lvl = 1 AND d.sec_id = n.sec_id AND d.prog_id = n.prog_id + ), + root_agg AS ( + SELECT n.*, d.plan_data, d.seq_dfip_data, d.approved_data, d.contract_summary_data, d.allocation_data, d.reserve_data, d.collegial_data, d.ckk_data, d.contract_data, d.booking_data, d.q1_data, d.q2_data, d.q3_data, d.q4_data, d.totals_data + FROM root_names n + LEFT JOIN lvl_data d + ON d.lvl = 3 AND d.sec_id = n.sec_id + ), + + -- Нулевой JSONB-шаблон (для пустых программ/проектов) + zero AS ( + SELECT '{}'::jsonb AS z + ), + + -- ═══ 5. UNION всех уровней ═════════════════════════════════════════════════ + unioned AS ( + -- ROOT — только из агрегатов (не имеет смысла пустой ROOT без строк) + SELECT + 'ROOT'::VARCHAR AS row_type, 0 AS depth, NULL::INT AS line_id, + jsonb_build_object('section_code', sec_code, 'name', sec_name, 'expense_item_id', sec_id) AS header, + plan_data, seq_dfip_data, approved_data, + contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, + contract_data, booking_data, + q1_data, q2_data, q3_data, q4_data, totals_data, + ARRAY[sec_id, 0, 0, 0]::INT[] AS sort_path + FROM root_agg + + UNION ALL + + -- GROUP — из агрегатов (программы с бюджетными строками) + SELECT + 'GROUP', 1, NULL, + jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id), + plan_data, seq_dfip_data, approved_data, + contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, + contract_data, booking_data, + q1_data, q2_data, q3_data, q4_data, totals_data, + ARRAY[sec_id, prog_id, 0, 0]::INT[] + FROM prog_agg + + UNION ALL + + -- GROUP — пустые программы (нет ни одной budget_line) + SELECT + 'GROUP', 1, NULL, + jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id), + tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved + tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve + tp_collegial, tp_ckk, -- collegial, ckk + tp_contract, tp_booking, -- contract, booking + tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals + ARRAY[sec_id, prog_id, 0, 0]::INT[] + FROM all_programs ap + JOIN tp_agg ON tp_agg.tp_id = 1 + WHERE NOT EXISTS ( + SELECT 1 FROM v3.budget_line bl + WHERE bl.budget_form_id = p_form_id + AND ( + bl.project_id = ap.prog_id -- прямая привязка к программе + OR bl.project_id IN (SELECT id FROM v3.form4_project pr -- через проект + WHERE pr.parent_id = ap.prog_id AND pr.level = 'project') + ) + ) + + UNION ALL + + -- ITEM — из агрегатов (проекты с бюджетными строками) + SELECT + 'ITEM', 2, NULL, + jsonb_build_object('section_code', sec_code, 'name', prj_name, + 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id), + plan_data, seq_dfip_data, approved_data, + contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, + contract_data, booking_data, + q1_data, q2_data, q3_data, q4_data, totals_data, + ARRAY[sec_id, prog_id, prj_id, 0]::INT[] + FROM prj_agg + + UNION ALL + + -- ITEM — пустые проекты (нет budget_line) + SELECT + 'ITEM', 2, NULL, + jsonb_build_object('section_code', sec_code, 'name', prj_name, + 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id), + tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved + tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve + tp_collegial, tp_ckk, -- collegial, ckk + tp_contract, tp_booking, -- contract, booking + tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals + ARRAY[sec_id, prog_id, prj_id, 0]::INT[] + FROM all_projects apr + JOIN tp_agg ON tp_agg.tp_id = 1 + WHERE NOT EXISTS ( + SELECT 1 FROM v3.budget_line bl + WHERE bl.budget_form_id = p_form_id + AND bl.project_id = apr.prj_id + ) + + UNION ALL + + -- INPUT — все строки бюджета + SELECT + 'INPUT', 3, line_id, + header || jsonb_build_object( + 'project_id', prj_id, 'project_name', prj_name, + 'program_id', prog_id, 'program_name', prog_name + ), + plan_data, seq_dfip_data, approved_data, + contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, + contract_data, booking_data, + q1_data, q2_data, q3_data, q4_data, totals_data, + ARRAY[sec_id, COALESCE(prog_id, 999999), COALESCE(CASE WHEN prj_id is null and prog_id is not null THEN 0 ELSE prj_id END, 999999), line_id]::INT[] + FROM inp + ) + + SELECT + u.row_type, u.depth, + ROW_NUMBER() OVER (ORDER BY u.sort_path) AS sort_order, + jsonb_build_object( + 'sort_path', u.sort_path, + 'line_id', u.line_id, + 'header', u.header, + 'plan', u.plan_data, + 'seq_dfip', u.seq_dfip_data, + 'approved', u.approved_data, + 'contract_summary', u.contract_summary_data, + 'allocation', u.allocation_data, + 'reserve', u.reserve_data, + 'collegial', u.collegial_data, + 'ckk', u.ckk_data, + 'contract', u.contract_data, + 'booking', u.booking_data, + 'q1', u.q1_data, + 'q2', u.q2_data, + 'q3', u.q3_data, + 'q4', u.q4_data, + 'totals', u.totals_data + ) AS data + FROM unioned u + ORDER BY u.sort_path; +$function$ +; diff --git a/api/alembic/versions/sql/0053_form4_sheet_sum.sql b/api/alembic/versions/sql/0053_form4_sheet_sum.sql deleted file mode 100644 index 46bea3d..0000000 --- a/api/alembic/versions/sql/0053_form4_sheet_sum.sql +++ /dev/null @@ -1,603 +0,0 @@ --- AURORA-1846: FORM_4, замена рекурсивного агрегата v3.jsonb_sum в --- v3.v_form4_sheet_jsonb на разворот листьев jsonb + GROUPING SETS. --- Тело — копия sql/0012_del_project.sql:1091-1617, изменён только блок --- «4. Агрегаты». v3.jsonb_sum / v3.jsonb_numeric_sum не удаляются (эталон в тестах). - -CREATE OR REPLACE FUNCTION v3.v_form4_sheet_jsonb(p_form_id integer, p_sheet character varying, p_sections text[] DEFAULT NULL::text[]) - RETURNS TABLE(row_type character varying, depth integer, sort_order bigint, data jsonb) - LANGUAGE sql - STABLE - SET jit TO 'off' -- оценка плана выше порога JIT, компиляция дороже выполнения (AURORA-1846) -AS $function$ - -- ═══ 1. Базовые INPUT-строки с расширенной иерархией ═══════════════════════ - WITH inp_raw AS ( - SELECT j.* - FROM v3.v_form4_sheet_lines_jsonb(p_form_id, p_sheet, p_sections) j - WHERE j.row_type = 'INPUT' - ), - inp AS ( - SELECT - i.*, - bl.project_id AS line_project_id, - - -- --- разрешение проекта --- - -- A. bl.project_id → project (level='project') - -- B. bl.project_id → program (level='program') — тогда проекта нет - CASE WHEN prj.id IS NOT NULL THEN prj.id END AS prj_id, - CASE WHEN prj.id IS NOT NULL THEN prj.name END AS prj_name, - - -- --- разрешение программы --- - -- A. через проект: prog_via_prj - -- B. напрямую: prog_direct - COALESCE(prog_via_prj.id, prog_direct.id) AS prog_id, - COALESCE(prog_via_prj.name, prog_direct.name) AS prog_name, - - -- --- section (depth=0) --- - sec.id AS sec_id, - sec.section_code AS sec_code, - sec.name AS sec_name - - FROM inp_raw i - JOIN v3.budget_line bl ON bl.id = i.line_id - - -- проект (level='project') - LEFT JOIN v3.form4_project prj - ON prj.id = bl.project_id AND prj.level = 'project' - - -- программа через проект - LEFT JOIN v3.form4_project prog_via_prj - ON prog_via_prj.id = prj.parent_id AND prog_via_prj.level = 'program' - - -- программа напрямую (bl.project_id → program) - LEFT JOIN v3.form4_project prog_direct - ON prog_direct.id = bl.project_id AND prog_direct.level = 'program' - - -- раздел depth=0 (через expense_item) - JOIN v3.expense_item ei ON ei.id = bl.expense_item_id - LEFT JOIN LATERAL ( - WITH RECURSIVE up AS ( - SELECT id, parent_id, name, section_code, depth - FROM v3.expense_item WHERE id = ei.id - UNION ALL - SELECT e.id, e.parent_id, e.name, e.section_code, e.depth - FROM v3.expense_item e JOIN up u ON u.parent_id = e.id - ) - SELECT id, name, section_code FROM up WHERE depth = 0 LIMIT 1 - ) sec ON TRUE - ), - tp_agg AS ( - SELECT 1 AS tp_id, - jsonb_build_object( - 'q1', 0, 'q2', 0, - 'q3', 0, 'q4', 0, - 'year', 0, 'comment', null - ) AS tp_plan, - - - - jsonb_build_object( - 'q1', 0, 'q2', 0, - 'q3', 0, 'q4', 0, - 'year', 0, - 'justification', null - ) AS tp_seq_dfip, - - jsonb_build_object( - 'q1', 0, 'q2', 0, - 'q3', 0, 'q4', 0, - 'year', 0 - ) AS tp_approved, - - jsonb_build_object( - 'total', null, - 'reference', null, - 'counterparty', null, - 'deadline', null, - 'comment', null, - 'future_y1', null, - 'future_y2', null, - 'other_ssp', null, - 'centralized_flag', null - ) AS tp_contract_summary, - - jsonb_build_object( - 'contract_ref', null, - 'allocation_purpose', null - ) AS tp_allocation, - - jsonb_build_object( - 'q1', 0, 'q2', 0, - 'q3', 0, 'q4', 0, - 'year', 0, - 'justification', null - ) AS tp_reserve, - - jsonb_build_object( - 'approved', null, - 'protocol', null, - 'note', null - ) AS tp_collegial, - - jsonb_build_object( - 'ceiling', null, - 'q1', null, - 'q2', null, - 'q3', null, - 'q4', null, - 'rf_schedule', null, - 'delivery_deadline', null, - 'proc_plan', null, - 'proc_method', null, - 'comment', null - ) AS tp_ckk, - - jsonb_build_object( - 'act', null, - 'date', null, - 'scheme', null, - 'addenda', null, - 'ceiling', null, - 'comment', null, - 'subject', null, - 'currency', null, - 'deadline', null, - 'vat_rate', null, - 'reference', null, - 'q1', null, - 'q2', null, - 'q3', null, - 'q4', null, - 'rf_schedule', null, - 'counterparty', null, - 'exchange_rate', null, - 'amount_foreign', null - ) AS tp_contract, - - jsonb_build_object( - 'y2026', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null), - 'y2027', jsonb_build_object('q1', null, 'q2', null, 'q3', null, 'q4', null) - ) AS tp_booking, - - jsonb_build_object( - 'total', 0, - 'adj_rf', null, - 'pay_ho', null, - 'pay_rf', null, - 'adj_ssp', null, - 'booking', null, - 'pay_act', null, - 'pay_date', null, - 'actual_m1', null, - 'actual_m2', null, - 'actual_m3', null, - 'pay_amount', null, - 'adj_comment', null, - 'adj_current', null, - 'adj_reserve', null, - 'pay_comment', null, - 'transfer_q2', null, - 'transfer_q3', null, - 'transfer_q4', null, - 'transfer_econ', null, - 'actual_quarter', 0, - 'corrected_plan', 0, - 'residual_after_actual', 0, - 'residual_after_booking', 0 - ) AS tp_q1, - - jsonb_build_object( - 'target_change', null, - 'base_correction', null, - 'base_correction_comment', null, - 'revision_inc', null, - 'revision_seq', null, - 'revision_comment', null, - 'new_plan', 0, - 'adj_current', null, - 'adj_ssp', null, - 'adj_rf', null, - 'adj_reserve', null, - 'adj_comment', null, - 'corrected_plan', 0, - 'pay_date', null, - 'pay_amount', null, - 'pay_ho', null, - 'pay_rf', null, - 'pay_comment', null, - 'pay_act', null, - 'booking', null, - 'actual_m1', null, - 'actual_m2', null, - 'actual_m3', null, - 'actual_quarter', 0, - 'residual_after_booking', 0, - 'residual_after_actual', 0, - 'transfer_q3', null, - 'transfer_q4', null, - 'transfer_econ', null, - 'total', 0 - ) AS tp_q2, - - jsonb_build_object( - 'target_change', null, - 'base_correction', null, - 'base_correction_comment', null, - 'revision_inc', null, - 'revision_seq', null, - 'revision_comment', null, - 'new_plan', 0, - 'adj_current', null, - 'adj_ssp', null, - 'adj_rf', null, - 'adj_reserve', null, - 'adj_comment', null, - 'corrected_plan', 0, - 'pay_date', null, - 'pay_amount', null, - 'pay_ho', null, - 'pay_rf', null, - 'pay_comment', null, - 'pay_act', null, - 'booking', null, - 'actual_m1', null, - 'actual_m2', null, - 'actual_m3', null, - 'actual_quarter', 0, - 'residual_after_booking', 0, - 'residual_after_actual', 0, - 'transfer_q4', null, - 'transfer_econ', null, - 'total', 0 - ) AS tp_q3, - - jsonb_build_object( - 'target_change', null, - 'base_correction', null, - 'base_correction_comment', null, - 'revision_inc', null, - 'revision_seq', null, - 'revision_comment', null, - 'new_plan', 0, - 'adj_current', null, - 'adj_ssp', null, - 'adj_rf', null, - 'adj_reserve', null, - 'adj_comment', null, - 'corrected_plan', 0, - 'pay_date', null, - 'pay_amount', null, - 'pay_ho', null, - 'pay_rf', null, - 'pay_comment', null, - 'pay_act', null, - 'booking', null, - 'actual_m1', null, - 'actual_m2', null, - 'actual_m3', null, - 'actual_spod', null, - 'actual_quarter', 0, - 'residual_after_booking', 0, - 'residual_after_actual', 0, - 'transfer_econ', null, - 'total', 0 - ) AS tp_q4, - jsonb_build_object( - 'fact_year', 0 - ) AS tp_totals - - - - - - ), - -- ═══ 2. Все программы (включая пустые) ═════════════════════════════════════ - all_programs AS ( - SELECT - fp.id AS prog_id, - fp.name AS prog_name, - fp.section_code, - sec.id AS sec_id, - sec.section_code AS sec_code, - sec.name AS sec_name - FROM v3.form4_project fp - LEFT JOIN LATERAL ( - SELECT id, section_code, name - FROM v3.expense_item - WHERE section_code = fp.section_code AND depth = 0 - LIMIT 1 - ) sec ON TRUE - WHERE fp.level = 'program' - AND (p_sections IS NULL OR fp.section_code = ANY(p_sections)) - AND (fp.section_code = p_sheet) AND fp.form_id = p_form_id - ), - - -- ═══ 3. Все проекты под программами (включая пустые) ═══════════════════════ - all_projects AS ( - SELECT - prj.id AS prj_id, - prj.name AS prj_name, - prj.parent_id AS prog_id, - ap.sec_id, ap.sec_code, ap.sec_name - FROM v3.form4_project prj - JOIN all_programs ap ON ap.prog_id = prj.parent_id - WHERE prj.level = 'project' AND (ap.section_code = p_sheet) - ), - - -- ═══ 4. Агрегаты с финансовыми данными (только из inp) ════════════════════ - -- Замена рекурсивного агрегата v3.jsonb_sum (AURORA-1846): листья jsonb - -- разворачиваются в строки, суммируются GROUPING SETS по трём уровням - -- (раздел / программа / проект) и собираются обратно в jsonb. - -- Правила те же, что у v3.jsonb_numeric_sum: числа складываются, нечисловые - -- игнорируются, если по пути есть число; текст/null сохраняются, если путь - -- встретился в группе один раз; иначе JSON null; NULL-секция даёт NULL. - - -- Имена групп (без jsonb) - prj_names AS ( - SELECT - sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name, - prog_id, MAX(prog_name) AS prog_name, - prj_id, MAX(prj_name) AS prj_name - FROM inp WHERE prj_id IS NOT NULL - GROUP BY sec_id, prog_id, prj_id - ), - prog_names AS ( - SELECT - sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name, - prog_id, MAX(prog_name) AS prog_name - FROM inp WHERE prog_id IS NOT NULL - GROUP BY sec_id, prog_id - ), - root_names AS ( - SELECT - sec_id, MAX(sec_code) AS sec_code, MAX(sec_name) AS sec_name - FROM inp - GROUP BY sec_id - ), - - -- Листья jsonb: (колонка, ключ 1-го уровня, ключ 2-го уровня или NULL, значение) - leaves AS ( - SELECT - i.sec_id, i.prog_id, i.prj_id, - c.col, e1.key AS k1, e2.key AS k2, - COALESCE(e2.value, e1.value) AS val - FROM inp i - CROSS JOIN LATERAL (VALUES - ('plan', i.plan_data), - ('seq_dfip', i.seq_dfip_data), - ('approved', i.approved_data), - ('contract_summary', i.contract_summary_data), - ('allocation', i.allocation_data), - ('reserve', i.reserve_data), - ('collegial', i.collegial_data), - ('ckk', i.ckk_data), - ('contract', i.contract_data), - ('booking', i.booking_data), - ('q1', i.q1_data), - ('q2', i.q2_data), - ('q3', i.q3_data), - ('q4', i.q4_data), - ('totals', i.totals_data) - ) AS c(col, v) - CROSS JOIN LATERAL jsonb_each( - CASE WHEN jsonb_typeof(c.v) = 'object' THEN c.v END - ) AS e1 - LEFT JOIN LATERAL jsonb_each( - CASE WHEN jsonb_typeof(e1.value) = 'object' THEN e1.value END - ) AS e2 ON TRUE - ), - - -- Суммы листьев сразу по трём уровням (lvl: 3 раздел, 1 программа, 0 проект) - leaf_agg AS ( - SELECT - GROUPING(prog_id, prj_id) AS lvl, - sec_id, prog_id, prj_id, col, k1, k2, - COUNT(*) AS n, - COUNT(*) FILTER (WHERE jsonb_typeof(val) = 'number') AS n_num, - SUM((val #>> '{}')::numeric) FILTER (WHERE jsonb_typeof(val) = 'number') AS s, - (array_agg(val))[1] AS one - FROM leaves - GROUP BY GROUPING SETS ( - (sec_id, col, k1, k2), - (sec_id, prog_id, col, k1, k2), - (sec_id, prog_id, prj_id, col, k1, k2) - ) - ), - leaf_val AS ( - SELECT - lvl, sec_id, prog_id, prj_id, col, k1, k2, - CASE - WHEN n_num > 0 THEN to_jsonb(s) - WHEN n = 1 THEN one - ELSE 'null'::jsonb - END AS v - FROM leaf_agg - WHERE NOT (lvl = 1 AND prog_id IS NULL) - AND NOT (lvl = 0 AND prj_id IS NULL) - ), - -- Сборка второго уровня вложенности (booking.y2026.q1 → объект по ключу k1) - k1_val AS ( - SELECT - lvl, sec_id, prog_id, prj_id, col, k1, - CASE - WHEN bool_or(k2 IS NOT NULL) THEN jsonb_object_agg(k2, v) FILTER (WHERE k2 IS NOT NULL) - ELSE (array_agg(v))[1] - END AS v - FROM leaf_val - GROUP BY lvl, sec_id, prog_id, prj_id, col, k1 - ), - -- Сборка по колонкам: одна строка на группу - lvl_data AS ( - SELECT - lvl, sec_id, prog_id, prj_id, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'plan') AS plan_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'seq_dfip') AS seq_dfip_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'approved') AS approved_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'contract_summary') AS contract_summary_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'allocation') AS allocation_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'reserve') AS reserve_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'collegial') AS collegial_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'ckk') AS ckk_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'contract') AS contract_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'booking') AS booking_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'q1') AS q1_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'q2') AS q2_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'q3') AS q3_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'q4') AS q4_data, - jsonb_object_agg(k1, v) FILTER (WHERE col = 'totals') AS totals_data - FROM k1_val - GROUP BY lvl, sec_id, prog_id, prj_id - ), - - prj_agg AS ( - SELECT n.*, d.plan_data, d.seq_dfip_data, d.approved_data, d.contract_summary_data, d.allocation_data, d.reserve_data, d.collegial_data, d.ckk_data, d.contract_data, d.booking_data, d.q1_data, d.q2_data, d.q3_data, d.q4_data, d.totals_data - FROM prj_names n - LEFT JOIN lvl_data d - ON d.lvl = 0 AND d.sec_id = n.sec_id AND d.prog_id = n.prog_id AND d.prj_id = n.prj_id - ), - prog_agg AS ( - SELECT n.*, d.plan_data, d.seq_dfip_data, d.approved_data, d.contract_summary_data, d.allocation_data, d.reserve_data, d.collegial_data, d.ckk_data, d.contract_data, d.booking_data, d.q1_data, d.q2_data, d.q3_data, d.q4_data, d.totals_data - FROM prog_names n - LEFT JOIN lvl_data d - ON d.lvl = 1 AND d.sec_id = n.sec_id AND d.prog_id = n.prog_id - ), - root_agg AS ( - SELECT n.*, d.plan_data, d.seq_dfip_data, d.approved_data, d.contract_summary_data, d.allocation_data, d.reserve_data, d.collegial_data, d.ckk_data, d.contract_data, d.booking_data, d.q1_data, d.q2_data, d.q3_data, d.q4_data, d.totals_data - FROM root_names n - LEFT JOIN lvl_data d - ON d.lvl = 3 AND d.sec_id = n.sec_id - ), - - -- Нулевой JSONB-шаблон (для пустых программ/проектов) - zero AS ( - SELECT '{}'::jsonb AS z - ), - - -- ═══ 5. UNION всех уровней ═════════════════════════════════════════════════ - unioned AS ( - -- ROOT — только из агрегатов (не имеет смысла пустой ROOT без строк) - SELECT - 'ROOT'::VARCHAR AS row_type, 0 AS depth, NULL::INT AS line_id, - jsonb_build_object('section_code', sec_code, 'name', sec_name, 'expense_item_id', sec_id) AS header, - plan_data, seq_dfip_data, approved_data, - contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, - contract_data, booking_data, - q1_data, q2_data, q3_data, q4_data, totals_data, - ARRAY[sec_id, 0, 0, 0]::INT[] AS sort_path - FROM root_agg - - UNION ALL - - -- GROUP — из агрегатов (программы с бюджетными строками) - SELECT - 'GROUP', 1, NULL, - jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id), - plan_data, seq_dfip_data, approved_data, - contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, - contract_data, booking_data, - q1_data, q2_data, q3_data, q4_data, totals_data, - ARRAY[sec_id, prog_id, 0, 0]::INT[] - FROM prog_agg - - UNION ALL - - -- GROUP — пустые программы (нет ни одной budget_line) - SELECT - 'GROUP', 1, NULL, - jsonb_build_object('section_code', sec_code, 'name', prog_name, 'program_id', prog_id, 'expense_item_id', sec_id), - tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved - tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve - tp_collegial, tp_ckk, -- collegial, ckk - tp_contract, tp_booking, -- contract, booking - tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals - ARRAY[sec_id, prog_id, 0, 0]::INT[] - FROM all_programs ap - JOIN tp_agg ON tp_agg.tp_id = 1 - WHERE NOT EXISTS ( - SELECT 1 FROM v3.budget_line bl - WHERE bl.budget_form_id = p_form_id - AND ( - bl.project_id = ap.prog_id -- прямая привязка к программе - OR bl.project_id IN (SELECT id FROM v3.form4_project pr -- через проект - WHERE pr.parent_id = ap.prog_id AND pr.level = 'project') - ) - ) - - UNION ALL - - -- ITEM — из агрегатов (проекты с бюджетными строками) - SELECT - 'ITEM', 2, NULL, - jsonb_build_object('section_code', sec_code, 'name', prj_name, - 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id), - plan_data, seq_dfip_data, approved_data, - contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, - contract_data, booking_data, - q1_data, q2_data, q3_data, q4_data, totals_data, - ARRAY[sec_id, prog_id, prj_id, 0]::INT[] - FROM prj_agg - - UNION ALL - - -- ITEM — пустые проекты (нет budget_line) - SELECT - 'ITEM', 2, NULL, - jsonb_build_object('section_code', sec_code, 'name', prj_name, - 'program_id', prog_id, 'project_id', prj_id, 'expense_item_id', sec_id), - tp_plan, tp_seq_dfip, tp_approved, -- plan, seq_dfip, approved - tp_contract_summary, tp_allocation, tp_reserve, -- contract_summary, allocation, reserve - tp_collegial, tp_ckk, -- collegial, ckk - tp_contract, tp_booking, -- contract, booking - tp_q1, tp_q2, tp_q3, tp_q4, tp_totals, -- q1-q4, totals - ARRAY[sec_id, prog_id, prj_id, 0]::INT[] - FROM all_projects apr - JOIN tp_agg ON tp_agg.tp_id = 1 - WHERE NOT EXISTS ( - SELECT 1 FROM v3.budget_line bl - WHERE bl.budget_form_id = p_form_id - AND bl.project_id = apr.prj_id - ) - - UNION ALL - - -- INPUT — все строки бюджета - SELECT - 'INPUT', 3, line_id, - header || jsonb_build_object( - 'project_id', prj_id, 'project_name', prj_name, - 'program_id', prog_id, 'program_name', prog_name - ), - plan_data, seq_dfip_data, approved_data, - contract_summary_data, allocation_data, reserve_data, collegial_data, ckk_data, - contract_data, booking_data, - q1_data, q2_data, q3_data, q4_data, totals_data, - ARRAY[sec_id, COALESCE(prog_id, 999999), COALESCE(CASE WHEN prj_id is null and prog_id is not null THEN 0 ELSE prj_id END, 999999), line_id]::INT[] - FROM inp - ) - - SELECT - u.row_type, u.depth, - ROW_NUMBER() OVER (ORDER BY u.sort_path) AS sort_order, - jsonb_build_object( - 'sort_path', u.sort_path, - 'line_id', u.line_id, - 'header', u.header, - 'plan', u.plan_data, - 'seq_dfip', u.seq_dfip_data, - 'approved', u.approved_data, - 'contract_summary', u.contract_summary_data, - 'allocation', u.allocation_data, - 'reserve', u.reserve_data, - 'collegial', u.collegial_data, - 'ckk', u.ckk_data, - 'contract', u.contract_data, - 'booking', u.booking_data, - 'q1', u.q1_data, - 'q2', u.q2_data, - 'q3', u.q3_data, - 'q4', u.q4_data, - 'totals', u.totals_data - ) AS data - FROM unioned u - ORDER BY u.sort_path; -$function$ -; -- 2.47.2