Merge pull request 'fixes-form: добавил новые статьи' (#164) from fixes-form into test
Reviewed-on: #164
This commit is contained in:
commit
9ea88f99e9
15
api/alembic/versions/0028_summary2_cap_smeta_type.py
Normal file
15
api/alembic/versions/0028_summary2_cap_smeta_type.py
Normal file
@ -0,0 +1,15 @@
|
||||
from sql_migration import run_sql_file_migration
|
||||
|
||||
|
||||
revision = "0028"
|
||||
down_revision = "0027"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
run_sql_file_migration("0028_summary2_cap_smeta_type.sql")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
pass
|
||||
15
api/alembic/versions/0029_expense_items_fixes.py
Normal file
15
api/alembic/versions/0029_expense_items_fixes.py
Normal file
@ -0,0 +1,15 @@
|
||||
from sql_migration import run_sql_file_migration
|
||||
|
||||
|
||||
revision = "0029"
|
||||
down_revision = "0028"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
run_sql_file_migration("0029_expense_items_fixes.sql")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
pass
|
||||
436
api/alembic/versions/sql/0028_summary2_cap_smeta_type.sql
Normal file
436
api/alembic/versions/sql/0028_summary2_cap_smeta_type.sql
Normal file
@ -0,0 +1,436 @@
|
||||
CREATE OR REPLACE FUNCTION v3.v_svod2_go(
|
||||
p_year integer,
|
||||
p_org_unit_ids integer[] DEFAULT NULL,
|
||||
p_offset integer DEFAULT NULL,
|
||||
p_limit integer DEFAULT NULL,
|
||||
p_sort_by varchar DEFAULT 'org_name',
|
||||
p_sort_direction varchar DEFAULT 'asc'
|
||||
)
|
||||
RETURNS TABLE(
|
||||
source_form varchar, source_id integer, source_org_unit_id integer,
|
||||
org_name varchar, smeta_type varchar,
|
||||
source_line_id integer, sort_order bigint, data jsonb
|
||||
)
|
||||
LANGUAGE sql STABLE SET search_path TO 'v3', 'pg_catalog'
|
||||
AS $function$
|
||||
WITH empty_sections AS MATERIALIZED (
|
||||
SELECT
|
||||
(to_jsonb(jsonb_populate_record(NULL::v3.plan, '{}'::jsonb)) - 'line_id')
|
||||
|| jsonb_build_object('plan_year', NULL) AS plan,
|
||||
(to_jsonb(jsonb_populate_record(NULL::v3.sequestration, '{}'::jsonb))
|
||||
- 'id' - 'line_id' - 'actor') || jsonb_build_object('adj_year', NULL) AS sequestration,
|
||||
(to_jsonb(jsonb_populate_record(NULL::v3.reserve, '{}'::jsonb)) - 'line_id')
|
||||
|| jsonb_build_object('amount_year', NULL) AS reserve,
|
||||
jsonb_build_object(
|
||||
'approved_q1', NULL, 'approved_q2', NULL,
|
||||
'approved_q3', NULL, 'approved_q4', NULL,
|
||||
'approved_year', NULL
|
||||
) AS approved,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.contract_summary, '{}'::jsonb)) - 'line_id' AS contract_summary,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.allocation, '{}'::jsonb)) - 'line_id' AS allocation,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.collegial_approval, '{}'::jsonb)) - 'line_id' AS collegial,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.ckk, '{}'::jsonb)) - 'line_id' AS ckk,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.contract_detail, '{}'::jsonb)) - 'line_id' AS contract_detail,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.booking, '{}'::jsonb)) - 'id' - 'line_id' AS booking,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.budget_line_quarter, '{}'::jsonb))
|
||||
- 'line_id' - 'quarter' AS quarter
|
||||
), eligible_lines AS (
|
||||
SELECT
|
||||
bl.id AS line_id,
|
||||
bf.form_type_code,
|
||||
bf.id AS form_id,
|
||||
bf.org_unit_id,
|
||||
ou.title AS org_name,
|
||||
ei.section_code,
|
||||
ei.item_id,
|
||||
CASE ei.sheet WHEN 'AHR' THEN 'АХР' WHEN 'CAP' THEN 'КВ'
|
||||
WHEN 'OPER' THEN 'Операц' END::varchar AS smeta_type
|
||||
FROM v3.budget_form bf
|
||||
JOIN v3.budget_line bl ON bl.budget_form_id = bf.id
|
||||
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
|
||||
JOIN v3.contract_detail cd ON cd.line_id = bl.id
|
||||
LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id
|
||||
WHERE bf.year = p_year
|
||||
AND bf.form_type_code IN ('FORM_1', 'FORM_4')
|
||||
AND ei.sheet IN ('AHR', 'CAP', 'OPER')
|
||||
AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = 0
|
||||
OR bf.org_unit_id = ANY(p_org_unit_ids))
|
||||
), numbered_lines AS (
|
||||
SELECT el.*,
|
||||
row_number() OVER (
|
||||
ORDER BY
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
|
||||
THEN el.org_name END ASC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
|
||||
THEN el.org_name END DESC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
|
||||
THEN el.item_id END ASC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
|
||||
THEN el.item_id END DESC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'asc'
|
||||
THEN el.section_code END ASC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'desc'
|
||||
THEN el.section_code END DESC NULLS LAST,
|
||||
el.form_type_code, el.form_id, el.line_id
|
||||
) AS sort_order
|
||||
FROM eligible_lines el
|
||||
), page AS MATERIALIZED (
|
||||
SELECT * FROM numbered_lines
|
||||
ORDER BY sort_order
|
||||
LIMIT p_limit OFFSET COALESCE(p_offset, 0)
|
||||
), booking_data AS (
|
||||
SELECT b.line_id,
|
||||
jsonb_agg(to_jsonb(b) - 'id' - 'line_id' ORDER BY b.quarter, b.source) AS booking
|
||||
FROM page pg
|
||||
JOIN v3.booking b ON b.line_id = pg.line_id
|
||||
GROUP BY b.line_id
|
||||
)
|
||||
SELECT
|
||||
pg.form_type_code,
|
||||
pg.form_id,
|
||||
pg.org_unit_id,
|
||||
pg.org_name,
|
||||
pg.smeta_type,
|
||||
pg.line_id,
|
||||
pg.sort_order,
|
||||
jsonb_build_object(
|
||||
'line_id', bl.id,
|
||||
'header', jsonb_build_object(
|
||||
'section_code', ei.section_code, 'item_id', ei.item_id,
|
||||
'num_group', ei.num_group_id, 'name', COALESCE(bl.name, ei.name),
|
||||
'expense_item_id', ei.id, 'justification', bl.justification,
|
||||
'internal_order', bl.internal_order, 'vsp_id', bl.vsp_id,
|
||||
'project_id', bl.project_id, 'direction', bl.direction,
|
||||
'smeta_direction', CASE bl.direction
|
||||
WHEN 'Support' THEN 'Поддержка'
|
||||
WHEN 'Development' THEN 'Развитие'
|
||||
ELSE NULL
|
||||
END,
|
||||
'source_form', pg.form_type_code, 'source_id', pg.form_id,
|
||||
'source_org_unit_id', pg.org_unit_id, 'org_name', pg.org_name,
|
||||
'smeta_type', pg.smeta_type),
|
||||
'plan', COALESCE(
|
||||
(to_jsonb(pl) - 'line_id') || jsonb_build_object(
|
||||
'plan_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
|
||||
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)),
|
||||
e.plan || jsonb_build_object('plan_year', NULL)),
|
||||
'sequestration', jsonb_build_object(
|
||||
'DFIP', COALESCE(
|
||||
(to_jsonb(sd) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
|
||||
'adj_year', COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
|
||||
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)),
|
||||
e.sequestration || jsonb_build_object('adj_year', NULL)),
|
||||
'SSP_GO', COALESCE(
|
||||
(to_jsonb(ss) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
|
||||
'adj_year', COALESCE(ss.adj_q1, 0) + COALESCE(ss.adj_q2, 0)
|
||||
+ COALESCE(ss.adj_q3, 0) + COALESCE(ss.adj_q4, 0)),
|
||||
e.sequestration || jsonb_build_object('adj_year', NULL))),
|
||||
'reserve', COALESCE(
|
||||
(to_jsonb(rv) - 'line_id') || jsonb_build_object(
|
||||
'amount_year', COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
|
||||
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)),
|
||||
e.reserve || jsonb_build_object('amount_year', NULL)),
|
||||
'approved', CASE WHEN pl.line_id IS NULL AND sd.id IS NULL
|
||||
AND rv.line_id IS NULL
|
||||
THEN e.approved
|
||||
ELSE jsonb_build_object(
|
||||
'approved_q1', COALESCE(pl.plan_q1, 0) + COALESCE(sd.adj_q1, 0)
|
||||
+ COALESCE(rv.amount_q1, 0),
|
||||
'approved_q2', COALESCE(pl.plan_q2, 0) + COALESCE(sd.adj_q2, 0)
|
||||
+ COALESCE(rv.amount_q2, 0),
|
||||
'approved_q3', COALESCE(pl.plan_q3, 0) + COALESCE(sd.adj_q3, 0)
|
||||
+ COALESCE(rv.amount_q3, 0),
|
||||
'approved_q4', COALESCE(pl.plan_q4, 0) + COALESCE(sd.adj_q4, 0)
|
||||
+ COALESCE(rv.amount_q4, 0),
|
||||
'approved_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
|
||||
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)
|
||||
+ COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
|
||||
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)
|
||||
+ COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
|
||||
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)) END,
|
||||
'contract_summary', COALESCE(to_jsonb(cs) - 'line_id', e.contract_summary),
|
||||
'allocation', COALESCE(to_jsonb(al) - 'line_id', e.allocation),
|
||||
'collegial', COALESCE(to_jsonb(ca) - 'line_id', e.collegial),
|
||||
'ckk', COALESCE(to_jsonb(ck) - 'line_id', e.ckk),
|
||||
'contract_detail', COALESCE(to_jsonb(cd) - 'line_id', e.contract_detail),
|
||||
'booking', COALESCE(bk.booking, jsonb_build_array(e.booking)),
|
||||
'q1', COALESCE(to_jsonb(q1) - 'line_id' - 'quarter', e.quarter),
|
||||
'q2', COALESCE(to_jsonb(q2) - 'line_id' - 'quarter', e.quarter),
|
||||
'q3', COALESCE(to_jsonb(q3) - 'line_id' - 'quarter', e.quarter),
|
||||
'q4', COALESCE(to_jsonb(q4) - 'line_id' - 'quarter', e.quarter)
|
||||
) AS data
|
||||
FROM page pg
|
||||
JOIN v3.budget_line bl ON bl.id = pg.line_id
|
||||
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
|
||||
JOIN v3.contract_detail cd ON cd.line_id = bl.id
|
||||
CROSS JOIN empty_sections e
|
||||
LEFT JOIN v3.plan pl ON pl.line_id = bl.id
|
||||
LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP'
|
||||
LEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = 'SSP_GO'
|
||||
LEFT JOIN v3.reserve rv ON rv.line_id = bl.id
|
||||
LEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id
|
||||
LEFT JOIN v3.allocation al ON al.line_id = bl.id
|
||||
LEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id
|
||||
LEFT JOIN v3.ckk ck ON ck.line_id = bl.id
|
||||
LEFT JOIN booking_data bk ON bk.line_id = bl.id
|
||||
LEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = 1
|
||||
LEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = 2
|
||||
LEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = 3
|
||||
LEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = 4
|
||||
ORDER BY pg.sort_order;
|
||||
$function$;
|
||||
|
||||
CREATE OR REPLACE FUNCTION v3.v_svod2_rf(
|
||||
p_year integer,
|
||||
p_org_unit_ids integer[] DEFAULT NULL,
|
||||
p_offset integer DEFAULT NULL,
|
||||
p_limit integer DEFAULT NULL,
|
||||
p_sort_by varchar DEFAULT 'org_name',
|
||||
p_sort_direction varchar DEFAULT 'asc'
|
||||
)
|
||||
RETURNS TABLE(
|
||||
source_form varchar, source_id integer, source_org_unit_id integer,
|
||||
org_name varchar, smeta_type varchar,
|
||||
source_line_id integer, sort_order bigint, data jsonb
|
||||
)
|
||||
LANGUAGE sql STABLE SET search_path TO 'v3', 'pg_catalog'
|
||||
AS $function$
|
||||
WITH empty_sections AS MATERIALIZED (
|
||||
SELECT
|
||||
(to_jsonb(jsonb_populate_record(NULL::v3.plan, '{}'::jsonb)) - 'line_id')
|
||||
|| jsonb_build_object('plan_year', NULL) AS plan,
|
||||
(to_jsonb(jsonb_populate_record(NULL::v3.sequestration, '{}'::jsonb))
|
||||
- 'id' - 'line_id' - 'actor') || jsonb_build_object('adj_year', NULL) AS sequestration,
|
||||
(to_jsonb(jsonb_populate_record(NULL::v3.reserve, '{}'::jsonb)) - 'line_id')
|
||||
|| jsonb_build_object('amount_year', NULL) AS reserve,
|
||||
jsonb_build_object(
|
||||
'approved_q1', NULL, 'approved_q2', NULL,
|
||||
'approved_q3', NULL, 'approved_q4', NULL,
|
||||
'approved_year', NULL
|
||||
) AS approved,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.contract_summary, '{}'::jsonb)) - 'line_id' AS contract_summary,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.allocation, '{}'::jsonb)) - 'line_id' AS allocation,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.collegial_approval, '{}'::jsonb)) - 'line_id' AS collegial,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.ckk, '{}'::jsonb)) - 'line_id' AS ckk,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.contract_detail, '{}'::jsonb)) - 'line_id' AS contract_detail,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.booking, '{}'::jsonb)) - 'id' - 'line_id' AS booking,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.budget_line_quarter, '{}'::jsonb))
|
||||
- 'line_id' - 'quarter' AS budget_quarter,
|
||||
to_jsonb(jsonb_populate_record(NULL::v3.rf_project_report_quarter, '{}'::jsonb))
|
||||
- 'rf_project_report_line_id' - 'quarter' AS report_quarter
|
||||
), eligible_lines AS (
|
||||
SELECT
|
||||
'FORM_2'::varchar AS form_type_code,
|
||||
bl.id AS line_id,
|
||||
bf.id AS source_id,
|
||||
bf.org_unit_id,
|
||||
ou.title AS org_name,
|
||||
ei.section_code,
|
||||
ei.item_id,
|
||||
CASE ei.sheet WHEN 'AHR' THEN 'АХР' WHEN 'CAP' THEN 'КВ'
|
||||
WHEN 'OPER' THEN 'Операц' END::varchar AS smeta_type
|
||||
FROM v3.budget_form bf
|
||||
JOIN v3.budget_line bl ON bl.budget_form_id = bf.id
|
||||
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
|
||||
JOIN v3.contract_detail cd ON cd.line_id = bl.id
|
||||
LEFT JOIN v3.org_unit ou ON ou.id = bf.org_unit_id
|
||||
WHERE bf.year = p_year AND bf.form_type_code = 'FORM_2'
|
||||
AND ei.sheet IN ('AHR', 'CAP', 'OPER')
|
||||
AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = 0
|
||||
OR bf.org_unit_id = ANY(p_org_unit_ids))
|
||||
UNION ALL
|
||||
SELECT
|
||||
'FORM_3'::varchar,
|
||||
rrl.id,
|
||||
rr.id,
|
||||
p.org_unit_id,
|
||||
ou.title,
|
||||
ei.section_code,
|
||||
ei.item_id,
|
||||
CASE ei.sheet WHEN 'AHR' THEN 'АХР' WHEN 'CAP' THEN 'КВ'
|
||||
WHEN 'OPER' THEN 'Операц' END::varchar
|
||||
FROM v3.rf_project_report rr
|
||||
JOIN v3.rf_project_year rpy ON rpy.id = rr.rf_project_year_id
|
||||
JOIN v3.project p ON p.id = rr.project_id
|
||||
JOIN v3.rf_project_report_line rrl ON rrl.rf_project_report_id = rr.id
|
||||
JOIN v3.expense_item ei ON ei.id = rrl.expense_item_id
|
||||
LEFT JOIN v3.org_unit ou ON ou.id = p.org_unit_id
|
||||
WHERE rpy.year = p_year AND ei.sheet IN ('AHR', 'CAP', 'OPER')
|
||||
AND (p_org_unit_ids IS NULL OR cardinality(p_org_unit_ids) = 0
|
||||
OR p.org_unit_id = ANY(p_org_unit_ids))
|
||||
), numbered_lines AS (
|
||||
SELECT el.*,
|
||||
row_number() OVER (
|
||||
ORDER BY
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
|
||||
THEN el.org_name END ASC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
|
||||
THEN el.org_name END DESC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'asc'
|
||||
THEN el.item_id END ASC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'org_name' AND lower(p_sort_direction) = 'desc'
|
||||
THEN el.item_id END DESC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'asc'
|
||||
THEN el.section_code END ASC NULLS LAST,
|
||||
CASE WHEN p_sort_by = 'section_code' AND lower(p_sort_direction) = 'desc'
|
||||
THEN el.section_code END DESC NULLS LAST,
|
||||
el.form_type_code, el.source_id, el.line_id
|
||||
) AS sort_order
|
||||
FROM eligible_lines el
|
||||
), page AS MATERIALIZED (
|
||||
SELECT * FROM numbered_lines
|
||||
ORDER BY sort_order
|
||||
LIMIT p_limit OFFSET COALESCE(p_offset, 0)
|
||||
), booking_data AS (
|
||||
SELECT b.line_id,
|
||||
jsonb_agg(to_jsonb(b) - 'id' - 'line_id' ORDER BY b.quarter, b.source) AS booking
|
||||
FROM page pg
|
||||
JOIN v3.booking b ON b.line_id = pg.line_id
|
||||
WHERE pg.form_type_code = 'FORM_2'
|
||||
GROUP BY b.line_id
|
||||
), form2_data AS (
|
||||
SELECT
|
||||
pg.form_type_code AS source_form, pg.source_id,
|
||||
pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,
|
||||
pg.line_id AS source_line_id, pg.sort_order,
|
||||
jsonb_build_object(
|
||||
'line_id', bl.id,
|
||||
'header', jsonb_build_object(
|
||||
'section_code', ei.section_code, 'item_id', ei.item_id,
|
||||
'num_group', ei.num_group_id, 'name', COALESCE(bl.name, ei.name),
|
||||
'expense_item_id', ei.id, 'justification', bl.justification,
|
||||
'internal_order', bl.internal_order, 'vsp_id', bl.vsp_id,
|
||||
'project_id', bl.project_id, 'direction', bl.direction,
|
||||
'smeta_direction', CASE bl.direction
|
||||
WHEN 'Support' THEN 'Поддержка'
|
||||
WHEN 'Development' THEN 'Развитие'
|
||||
ELSE NULL
|
||||
END,
|
||||
'source_form', pg.form_type_code, 'source_id', pg.source_id,
|
||||
'source_org_unit_id', pg.org_unit_id, 'org_name', pg.org_name,
|
||||
'smeta_type', pg.smeta_type),
|
||||
'plan', COALESCE(
|
||||
(to_jsonb(pl) - 'line_id') || jsonb_build_object(
|
||||
'plan_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
|
||||
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)),
|
||||
e.plan || jsonb_build_object('plan_year', NULL)),
|
||||
'sequestration', jsonb_build_object(
|
||||
'DFIP', COALESCE(
|
||||
(to_jsonb(sd) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
|
||||
'adj_year', COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
|
||||
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)),
|
||||
e.sequestration || jsonb_build_object('adj_year', NULL)),
|
||||
'SSP_GO', COALESCE(
|
||||
(to_jsonb(ss) - 'id' - 'line_id' - 'actor') || jsonb_build_object(
|
||||
'adj_year', COALESCE(ss.adj_q1, 0) + COALESCE(ss.adj_q2, 0)
|
||||
+ COALESCE(ss.adj_q3, 0) + COALESCE(ss.adj_q4, 0)),
|
||||
e.sequestration || jsonb_build_object('adj_year', NULL))),
|
||||
'reserve', COALESCE(
|
||||
(to_jsonb(rv) - 'line_id') || jsonb_build_object(
|
||||
'amount_year', COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
|
||||
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)),
|
||||
e.reserve || jsonb_build_object('amount_year', NULL)),
|
||||
'approved', CASE WHEN pl.line_id IS NULL AND sd.id IS NULL
|
||||
AND ss.id IS NULL AND rv.line_id IS NULL
|
||||
THEN e.approved
|
||||
ELSE jsonb_build_object(
|
||||
'approved_q1', COALESCE(pl.plan_q1, 0) + COALESCE(sd.adj_q1, 0)
|
||||
+ COALESCE(ss.adj_q1, 0) + COALESCE(rv.amount_q1, 0),
|
||||
'approved_q2', COALESCE(pl.plan_q2, 0) + COALESCE(sd.adj_q2, 0)
|
||||
+ COALESCE(ss.adj_q2, 0) + COALESCE(rv.amount_q2, 0),
|
||||
'approved_q3', COALESCE(pl.plan_q3, 0) + COALESCE(sd.adj_q3, 0)
|
||||
+ COALESCE(ss.adj_q3, 0) + COALESCE(rv.amount_q3, 0),
|
||||
'approved_q4', COALESCE(pl.plan_q4, 0) + COALESCE(sd.adj_q4, 0)
|
||||
+ COALESCE(ss.adj_q4, 0) + COALESCE(rv.amount_q4, 0),
|
||||
'approved_year', COALESCE(pl.plan_q1, 0) + COALESCE(pl.plan_q2, 0)
|
||||
+ COALESCE(pl.plan_q3, 0) + COALESCE(pl.plan_q4, 0)
|
||||
+ COALESCE(sd.adj_q1, 0) + COALESCE(sd.adj_q2, 0)
|
||||
+ COALESCE(sd.adj_q3, 0) + COALESCE(sd.adj_q4, 0)
|
||||
+ COALESCE(ss.adj_q1, 0) + COALESCE(ss.adj_q2, 0)
|
||||
+ COALESCE(ss.adj_q3, 0) + COALESCE(ss.adj_q4, 0)
|
||||
+ COALESCE(rv.amount_q1, 0) + COALESCE(rv.amount_q2, 0)
|
||||
+ COALESCE(rv.amount_q3, 0) + COALESCE(rv.amount_q4, 0)) END,
|
||||
'contract_summary', COALESCE(to_jsonb(cs) - 'line_id', e.contract_summary),
|
||||
'allocation', COALESCE(to_jsonb(al) - 'line_id', e.allocation),
|
||||
'collegial', COALESCE(to_jsonb(ca) - 'line_id', e.collegial),
|
||||
'ckk', COALESCE(to_jsonb(ck) - 'line_id', e.ckk),
|
||||
'contract_detail', COALESCE(to_jsonb(cd) - 'line_id', e.contract_detail),
|
||||
'booking', COALESCE(bk.booking, jsonb_build_array(e.booking)),
|
||||
'q1', COALESCE(to_jsonb(q1) - 'line_id' - 'quarter', e.budget_quarter),
|
||||
'q2', COALESCE(to_jsonb(q2) - 'line_id' - 'quarter', e.budget_quarter),
|
||||
'q3', COALESCE(to_jsonb(q3) - 'line_id' - 'quarter', e.budget_quarter),
|
||||
'q4', COALESCE(to_jsonb(q4) - 'line_id' - 'quarter', e.budget_quarter)
|
||||
) AS data
|
||||
FROM page pg
|
||||
JOIN v3.budget_line bl ON bl.id = pg.line_id
|
||||
JOIN v3.expense_item ei ON ei.id = bl.expense_item_id
|
||||
JOIN v3.contract_detail cd ON cd.line_id = bl.id
|
||||
CROSS JOIN empty_sections e
|
||||
LEFT JOIN v3.plan pl ON pl.line_id = bl.id
|
||||
LEFT JOIN v3.sequestration sd ON sd.line_id = bl.id AND sd.actor = 'DFIP'
|
||||
LEFT JOIN v3.sequestration ss ON ss.line_id = bl.id AND ss.actor = 'SSP_GO'
|
||||
LEFT JOIN v3.reserve rv ON rv.line_id = bl.id
|
||||
LEFT JOIN v3.contract_summary cs ON cs.line_id = bl.id
|
||||
LEFT JOIN v3.allocation al ON al.line_id = bl.id
|
||||
LEFT JOIN v3.collegial_approval ca ON ca.line_id = bl.id
|
||||
LEFT JOIN v3.ckk ck ON ck.line_id = bl.id
|
||||
LEFT JOIN booking_data bk ON bk.line_id = bl.id
|
||||
LEFT JOIN v3.budget_line_quarter q1 ON q1.line_id = bl.id AND q1.quarter = 1
|
||||
LEFT JOIN v3.budget_line_quarter q2 ON q2.line_id = bl.id AND q2.quarter = 2
|
||||
LEFT JOIN v3.budget_line_quarter q3 ON q3.line_id = bl.id AND q3.quarter = 3
|
||||
LEFT JOIN v3.budget_line_quarter q4 ON q4.line_id = bl.id AND q4.quarter = 4
|
||||
WHERE pg.form_type_code = 'FORM_2'
|
||||
), form3_data AS (
|
||||
SELECT
|
||||
pg.form_type_code AS source_form, pg.source_id,
|
||||
pg.org_unit_id AS source_org_unit_id, pg.org_name, pg.smeta_type,
|
||||
pg.line_id AS source_line_id, pg.sort_order,
|
||||
jsonb_build_object(
|
||||
'line_id', rrl.id,
|
||||
'header', jsonb_build_object(
|
||||
'section_code', ei.section_code, 'item_id', ei.item_id,
|
||||
'num_group', ei.num_group_id, 'name', ei.name,
|
||||
'expense_item_id', ei.id, 'project_id', rr.project_id,
|
||||
'report_type', rr.report_type,
|
||||
'smeta_direction', NULL,
|
||||
'source_form', pg.form_type_code, 'source_id', pg.source_id,
|
||||
'source_org_unit_id', pg.org_unit_id, 'org_name', pg.org_name,
|
||||
'smeta_type', pg.smeta_type),
|
||||
'plan', e.plan,
|
||||
'sequestration', jsonb_build_object(
|
||||
'DFIP', e.sequestration, 'SSP_GO', e.sequestration),
|
||||
'reserve', e.reserve, 'contract_summary', e.contract_summary,
|
||||
'approved', e.approved,
|
||||
'allocation', e.allocation, 'collegial', e.collegial,
|
||||
'ckk', e.ckk, 'contract_detail', e.contract_detail,
|
||||
'booking', jsonb_build_array(e.booking),
|
||||
'q1', COALESCE(to_jsonb(q1) - 'rf_project_report_line_id' - 'quarter', e.report_quarter),
|
||||
'q2', COALESCE(to_jsonb(q2) - 'rf_project_report_line_id' - 'quarter', e.report_quarter),
|
||||
'q3', COALESCE(to_jsonb(q3) - 'rf_project_report_line_id' - 'quarter', e.report_quarter),
|
||||
'q4', COALESCE(to_jsonb(q4) - 'rf_project_report_line_id' - 'quarter', e.report_quarter)
|
||||
) AS data
|
||||
FROM page pg
|
||||
JOIN v3.rf_project_report_line rrl ON rrl.id = pg.line_id
|
||||
JOIN v3.rf_project_report rr ON rr.id = pg.source_id
|
||||
AND rr.id = rrl.rf_project_report_id
|
||||
JOIN v3.expense_item ei ON ei.id = rrl.expense_item_id
|
||||
CROSS JOIN empty_sections e
|
||||
LEFT JOIN v3.rf_project_report_quarter q1
|
||||
ON q1.rf_project_report_line_id = rrl.id AND q1.quarter = 1
|
||||
LEFT JOIN v3.rf_project_report_quarter q2
|
||||
ON q2.rf_project_report_line_id = rrl.id AND q2.quarter = 2
|
||||
LEFT JOIN v3.rf_project_report_quarter q3
|
||||
ON q3.rf_project_report_line_id = rrl.id AND q3.quarter = 3
|
||||
LEFT JOIN v3.rf_project_report_quarter q4
|
||||
ON q4.rf_project_report_line_id = rrl.id AND q4.quarter = 4
|
||||
WHERE pg.form_type_code = 'FORM_3'
|
||||
), result_rows AS (
|
||||
SELECT * FROM form2_data
|
||||
UNION ALL
|
||||
SELECT * FROM form3_data
|
||||
)
|
||||
SELECT rr.source_form, rr.source_id, rr.source_org_unit_id, rr.org_name, rr.smeta_type,
|
||||
rr.source_line_id, rr.sort_order, rr.data
|
||||
FROM result_rows rr
|
||||
ORDER BY rr.sort_order;
|
||||
$function$;
|
||||
128
api/alembic/versions/sql/0029_expense_items_fixes.sql
Normal file
128
api/alembic/versions/sql/0029_expense_items_fixes.sql
Normal file
@ -0,0 +1,128 @@
|
||||
-- Исправления справочника статей расходов по файлу
|
||||
-- "План_исправления_таблиц_статей_расходов.docx".
|
||||
-- Правки, связанные с ГСМ, намеренно не включены.
|
||||
|
||||
-- Общие переименования.
|
||||
update v3.expense_item
|
||||
set name = 'Охр.инкассат перевоз'
|
||||
where item_id = 'R061063000'
|
||||
and num_group_id = '211320117';
|
||||
|
||||
update v3.expense_item
|
||||
set name = 'Взносы в орг/ассоц'
|
||||
where item_id = 'R061141000'
|
||||
and num_group_id = '214920158';
|
||||
|
||||
update v3.expense_item
|
||||
set name = 'Бланк ден/чек книжМЦ'
|
||||
where item_id = 'R064040032'
|
||||
and num_group_id = '402640197';
|
||||
|
||||
update v3.expense_item
|
||||
set name = 'Другие операционные доходы'
|
||||
where item_id = 'R014040037'
|
||||
and num_group_id is null;
|
||||
|
||||
-- Перенос двух статей НВНОД в раздел 1.15.6.
|
||||
update v3.expense_item
|
||||
set parent_id = 81,
|
||||
depth = 3
|
||||
where (item_id, num_group_id) in (
|
||||
('R061156019', '403540147'),
|
||||
('R061159019', '216220174')
|
||||
);
|
||||
|
||||
-- Раздел 1.14: коды по шаблону, включая добавление 1.14.7 для проектов.
|
||||
update v3.expense_item set item_id = '1.14.4' where id = 71;
|
||||
update v3.expense_item set item_id = '1.14.5' where id = 72;
|
||||
update v3.expense_item set item_id = '1.14.6' where id = 73;
|
||||
update v3.expense_item set item_id = '1.14.7' where id = 74;
|
||||
|
||||
insert into v3.expense_item_form_type (expense_item_id, form_type_code)
|
||||
values (74, 'FORM_1'), (74, 'FORM_2')
|
||||
on conflict (expense_item_id, form_type_code) do nothing;
|
||||
|
||||
-- Исправление ошибочного ID статьи по ПО информационной безопасности.
|
||||
update v3.expense_item
|
||||
set item_id = 'R061012024',
|
||||
direction = coalesce(direction, 'Support')
|
||||
where item_id = 'R061012025'
|
||||
and name = 'Внедрение и доработка внешними контрагентами: ПО информационной безопасности';
|
||||
|
||||
-- Статья "Расходы по выбытию: ПО информационной безопасности" для раздела 1.17.2.
|
||||
update v3.expense_item
|
||||
set direction = coalesce(direction, 'Support'),
|
||||
parent_id = 84,
|
||||
depth = 3
|
||||
where item_id = 'R061172024'
|
||||
and name = 'Расходы по выбытию: ПО информационной безопасности';
|
||||
|
||||
insert into v3.expense_item_form_type (expense_item_id, form_type_code)
|
||||
select id, form_type_code
|
||||
from v3.expense_item
|
||||
cross join (values ('FORM_1'), ('FORM_2')) as ft(form_type_code)
|
||||
where item_id = 'R061172024'
|
||||
and name = 'Расходы по выбытию: ПО информационной безопасности'
|
||||
on conflict (expense_item_id, form_type_code) do nothing;
|
||||
|
||||
-- Девять статей Операц уже есть в справочнике. Настраиваем только доступность
|
||||
-- для Сметы ССП, Сметы РФ и Проектной деятельности.
|
||||
with source(expense_item_id, form_type_code) as (
|
||||
values
|
||||
(736, 'FORM_4'), (745, 'FORM_2'), (745, 'FORM_4'),
|
||||
(800, 'FORM_1'), (800, 'FORM_2'), (800, 'FORM_4'),
|
||||
(801, 'FORM_1'), (801, 'FORM_2'), (801, 'FORM_4'),
|
||||
(802, 'FORM_1'), (802, 'FORM_2'), (802, 'FORM_4'),
|
||||
(803, 'FORM_1'), (803, 'FORM_2'), (803, 'FORM_4'),
|
||||
(804, 'FORM_1'), (804, 'FORM_2'), (804, 'FORM_4'),
|
||||
(805, 'FORM_1'), (805, 'FORM_2'), (805, 'FORM_4'),
|
||||
(806, 'FORM_1'), (806, 'FORM_2'), (806, 'FORM_4'),
|
||||
(807, 'FORM_1'), (807, 'FORM_2'), (807, 'FORM_4'),
|
||||
(808, 'FORM_1'), (808, 'FORM_2'), (808, 'FORM_4')
|
||||
)
|
||||
insert into v3.expense_item_form_type (expense_item_id, form_type_code)
|
||||
select expense_item_id, form_type_code
|
||||
from source
|
||||
on conflict (expense_item_id, form_type_code) do nothing;
|
||||
|
||||
-- Налоговые статьи раздела 5.00.0 для Сметы РФ.
|
||||
insert into v3.expense_item_form_type (expense_item_id, form_type_code)
|
||||
select id, 'FORM_2'
|
||||
from v3.expense_item
|
||||
where item_id in (
|
||||
'R065010000', 'R065020001', 'R065030012', 'R065040000',
|
||||
'R065050005', 'R065070000', 'R065090000', 'R065100000'
|
||||
)
|
||||
on conflict (expense_item_id, form_type_code) do nothing;
|
||||
|
||||
-- Проектная деятельность: добавить недостающие статьи АХР в FORM_4, кроме ГСМ.
|
||||
with form4_ahr(expense_item_id) as (
|
||||
values
|
||||
(777), (778), (779), (347), (780), (781), (782), (783),
|
||||
(784), (785), (786), (787), (788), (789), (790), (791),
|
||||
(461), (792), (793), (794), (795), (796), (797), (798),
|
||||
(477), (478)
|
||||
)
|
||||
insert into v3.expense_item_form_type (expense_item_id, form_type_code)
|
||||
select expense_item_id, 'FORM_4'
|
||||
from form4_ahr
|
||||
on conflict (expense_item_id, form_type_code) do nothing;
|
||||
|
||||
-- Проектная деятельность и проектные листы: исключить амортизацию и налоги
|
||||
-- из FORM_4, не удаляя записи из справочника и не затрагивая FORM_2.
|
||||
delete from v3.expense_item_form_type
|
||||
where form_type_code = 'FORM_4'
|
||||
and (
|
||||
expense_item_id in (746, 747, 760, 766)
|
||||
or expense_item_id between 748 and 759
|
||||
or expense_item_id between 761 and 765
|
||||
or expense_item_id between 767 and 774
|
||||
);
|
||||
|
||||
-- Проектные таблицы: исключить дубль перевозки валютных ценностей из формы.
|
||||
delete from v3.expense_item_form_type
|
||||
where form_type_code = 'FORM_4'
|
||||
and expense_item_id = 70;
|
||||
|
||||
select setval('v3.expense_item_id_seq', greatest((select max(id) from v3.expense_item), 808));
|
||||
refresh materialized view v3.mv_expense_item_tree;
|
||||
@ -5,9 +5,10 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from src.db.models.org_unit import OrgUnit
|
||||
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.orm import joinedload, with_loader_criteria
|
||||
|
||||
|
||||
from src.db.models.app_user import AppUser
|
||||
|
||||
|
||||
class OrgUnitRepository:
|
||||
@ -42,7 +43,12 @@ class OrgUnitRepository:
|
||||
query = query.where(*where)
|
||||
if load_users:
|
||||
query = query.options(
|
||||
joinedload(OrgUnit.users)
|
||||
joinedload(OrgUnit.users),
|
||||
with_loader_criteria(
|
||||
AppUser,
|
||||
AppUser.is_active.is_(True),
|
||||
include_aliases=True,
|
||||
),
|
||||
)
|
||||
|
||||
query = query.order_by(OrgUnit.id)
|
||||
@ -75,7 +81,12 @@ class OrgUnitRepository:
|
||||
query = select(OrgUnit).where(OrgUnit.id == org_unit_id)
|
||||
if load_users:
|
||||
query = query.options(
|
||||
joinedload(OrgUnit.users)
|
||||
joinedload(OrgUnit.users),
|
||||
with_loader_criteria(
|
||||
AppUser,
|
||||
AppUser.is_active.is_(True),
|
||||
include_aliases=True,
|
||||
),
|
||||
)
|
||||
|
||||
return (await self.db.execute(query)).scalars().first()
|
||||
|
||||
@ -111,6 +111,8 @@ class UserRepository:
|
||||
async def logical_delete(self, user_id: int) -> bool:
|
||||
query = update(AppUser).where(AppUser.id == user_id).values(is_active=False)
|
||||
result = await self.db.execute(query)
|
||||
if result.rowcount > 0:
|
||||
await self.db.execute(delete(UserOrg).where(UserOrg.user_id == user_id))
|
||||
await self.db.commit()
|
||||
return result.rowcount > 0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user