Merge pull request 'sattelite-fix: добавил формулу для принтеров и мфу' (#177) from sattelite-fix into test

Reviewed-on: #177
This commit is contained in:
tsygankoviva 2026-09-25 10:30:24 +03:00
commit 94c18b4ca7
2 changed files with 128 additions and 0 deletions

View File

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

View File

@ -0,0 +1,113 @@
-- After 0033 some AHR expense items with num_group_id became depth=4.
-- AHR_LIMIT synchronization still required depth=3, so limit rows such as
-- "принтеры", "МФУ", and "копировальные аппараты" stopped matching
-- expense_item.num_group_id = '204620030'.
--
-- The same three limit rows also use a special quarterly amount formula:
-- qty * 0.57 * 10900 / 4. Other limit rows keep the previous formula.
CREATE OR REPLACE FUNCTION v3._form2_ahr_limit_amount(
p_name character varying,
p_unit character varying,
p_limit_with_vat numeric,
p_qty numeric
)
RETURNS numeric
LANGUAGE sql
IMMUTABLE
AS $function$
SELECT COALESCE(p_qty, 0) *
CASE
WHEN regexp_replace(
COALESCE(p_name, ''),
'^[[:space:]]*-[[:space:]]*',
''
) IN ('принтеры', 'МФУ', 'копировальные аппараты')
THEN 0.57 * 10900 / 4
ELSE COALESCE(p_limit_with_vat, 0) *
CASE
WHEN p_unit LIKE '%/год' THEN 0.25
WHEN p_unit LIKE '%/месяц' THEN 3
ELSE 1
END
END;
$function$;
DO $do$
DECLARE
v_signature regprocedure;
v_sql text;
v_next_sql text;
BEGIN
FOREACH v_signature IN ARRAY ARRAY[
'v3.v_form2_view(integer,character varying,text[])'::regprocedure,
'v3.sync_form2_ahr_satellite_lines(integer)'::regprocedure,
'v3.sync_form2_ahr_satellite_line(integer,character varying,integer)'::regprocedure
]
LOOP
v_sql := pg_get_functiondef(v_signature);
v_next_sql := regexp_replace(
v_sql,
$re$COALESCE\(fl\.qty_q([1-4]),[[:space:]]*0\)[[:space:]]*\*[[:space:]]*COALESCE\(lt\.limit_with_vat,[[:space:]]*0\)[[:space:]]*\*[[:space:]]*\(?[[:space:]]*CASE[[:space:]]+WHEN[[:space:]]+lt\.unit[[:space:]]+LIKE[[:space:]]+'%/год'[[:space:]]+THEN[[:space:]]+0\.25[[:space:]]+WHEN[[:space:]]+lt\.unit[[:space:]]+LIKE[[:space:]]+'%/месяц'[[:space:]]+THEN[[:space:]]+3[[:space:]]+ELSE[[:space:]]+1[[:space:]]+END[[:space:]]*\)?$re$,
$replace$v3._form2_ahr_limit_amount(lt.name, lt.unit, lt.limit_with_vat, fl.qty_q\1)$replace$,
'g'
);
IF v_next_sql = v_sql THEN
RAISE EXCEPTION 'Expected AHR limit amount expression was not found in %', v_signature;
END IF;
EXECUTE v_next_sql;
END LOOP;
END;
$do$;
DO $do$
DECLARE
v_signature regprocedure;
v_sql text;
v_next_sql text;
BEGIN
FOREACH v_signature IN ARRAY ARRAY[
'v3.sync_form2_ahr_satellite_lines(integer)'::regprocedure,
'v3.sync_form2_ahr_satellite_line(integer,character varying,integer)'::regprocedure,
'v3.get_form2_ahr_satellite_delta(integer,character varying,integer)'::regprocedure,
'v3.is_form2_ahr_satellite_line(integer,integer)'::regprocedure
]
LOOP
v_sql := pg_get_functiondef(v_signature);
v_next_sql := regexp_replace(
v_sql,
'AND\s+ei\.depth\s*=\s*3\s+AND\s*\(\s*ei\.item_id\s*=\s*lt\.expense_item_code\s+OR\s+ei\.num_group_id\s*=\s*lt\.expense_item_code\s*\)',
E'AND (\n (ei.depth = 3 AND ei.item_id = lt.expense_item_code)\n OR ei.num_group_id = lt.expense_item_code\n )',
'g'
);
IF v_next_sql = v_sql THEN
IF v_sql ~ 'ei\.depth[[:space:]]*=[[:space:]]*3[[:space:]]+AND[[:space:]]+ei\.item_id[[:space:]]*=[[:space:]]*lt\.expense_item_code[[:space:]]*\)[[:space:]]+OR[[:space:]]+ei\.num_group_id[[:space:]]*=[[:space:]]*lt\.expense_item_code' THEN
CONTINUE;
END IF;
RAISE EXCEPTION 'Expected depth=3 limit-template matcher was not found in %', v_signature;
END IF;
EXECUTE v_next_sql;
END LOOP;
END;
$do$;
DO $do$
DECLARE
v_form_id integer;
BEGIN
FOR v_form_id IN
SELECT id
FROM v3.budget_form
WHERE form_type_code = 'FORM_2'
LOOP
PERFORM v3.sync_form2_ahr_satellite_lines(v_form_id);
END LOOP;
END;
$do$;