AURORA-1907: признак источника строки АХР и раздельные суммы лимита/сверх лимита #271
Open
aep
wants to merge 5 commits from
feat/270-aurora-1907-source-sheet into test
pull from: feat/270-aurora-1907-source-sheet
merge into: RSHB:test
RSHB:main
RSHB:feat/272-aurora-1887-ahr-hide-satellite-rows
RSHB:feat/266-aurora-1897-ahr-limit-period-vat-units
RSHB:feat/265-aurora-1909-ahr-manual-row-capture
RSHB:feat/264-aurora-1895-formula-localstorage
RSHB:feat/254-aurora-1906-spod-column
RSHB:feat/255-aurora-1938-transfer-econ-calc
RSHB:feat/250-aurora-1888-stages-role-filter
RSHB:feat/253-aurora-1905-form1-form4-export-layout
RSHB:feat/252-aurora-1902-form2-export-layout
RSHB:feat/251-aurora-1901-smeta-rf-column-order
RSHB:feat/249-aurora-1936-row-delete-confirm
RSHB:feat/248-aurora-1877-token-refresh
RSHB:feat/246-aurora-1944-wheel-scroll-step
RSHB:feat/236-aurora-1843-svod2-server-paging-perf
RSHB:feat/236-aurora-1843-svod2-server-paging-web
RSHB:feat/236-aurora-1843-svod2-server-paging
RSHB:feat/214-aurora-1841-dict-vsp-virtual
RSHB:feat/220-aurora-1842-svod2-column-virtual
RSHB:feat/216-aurora-1846-form4-sheet-sum
RSHB:feat/235-aurora-1850-upd-form-cells-subtree
RSHB:feat/233-aurora-1848-sheet-json-no-pydantic-b
RSHB:feat/234-aurora-1839-cell-memo
RSHB:feat/233-aurora-1848-sheet-json-no-pydantic
RSHB:feat/237-aurora-1845-ws-connection-cache
RSHB:feat/215-aurora-1844-upd-form-cells-full-rows
RSHB:feat/226-aurora-1837-cell-styles-css
RSHB:feat/207-aurora-1831-project-tn-race
RSHB:feat/208-aurora-1832-phase-dates-tz
RSHB:feat/209-aurora-1833-greenlet-dev
RSHB:feat/206-aurora-1830-users-me-local-email
RSHB:feat/212-aurora-1838-ws-immutable-update
RSHB:feat/211-aurora-1836-row-measure
RSHB:feat/205-aurora-1922-pg15-migration-0012
RSHB:feat/213-aurora-1840-sheet-modals
RSHB:feat/210-aurora-1835-svod1-formatter
RSHB:test
RSHB:svod2-filter-fix2
RSHB:indent-export
RSHB:export-hierarchy
RSHB:svod2-filter-fix
RSHB:fix-id-column
RSHB:export-year-fix
RSHB:form3-source
RSHB:columns-svod-2
RSHB:export-optimize-refresh
RSHB:last-column
RSHB:svod-fix
RSHB:fix-columns
RSHB:form3-expense
RSHB:sattelite-fix
RSHB:delete-sattelite-rows
RSHB:form3-pages
RSHB:form1-sub_sub-fix
RSHB:sort-fix
RSHB:fixes-form
RSHB:new-expenses
RSHB:new-rows
RSHB:fix-style
RSHB:phase-template-edit
RSHB:fixes
RSHB:add-btn-reset-filter
RSHB:vsp-choice-fix
RSHB:project-filters-fix
RSHB:width-column-header-name
RSHB:task-filter-navigation
RSHB:auth
RSHB:icons-program-project
RSHB:export-optimize
RSHB:org-unit-limits
RSHB:auth-v2
RSHB:tasks-filters
RSHB:insert-row-fix
RSHB:svod-roles
RSHB:new-role-fix
RSHB:phase-edit-fix
RSHB:new-role
RSHB:delete-from-cell
RSHB:svod-cahe-and-table-direction
RSHB:direction-stage-fix
RSHB:backslash-fix
RSHB:svod
RSHB:front-svod-form-1
RSHB:projects-filters
RSHB:remove-row-fix
RSHB:computed-fix
RSHB:modal-add-year-project
RSHB:name-fix
RSHB:audit-logs-projects
RSHB:meta-form-3
RSHB:project-back-fix
RSHB:fix-sticky-columns
RSHB:fixies-3-form
RSHB:tech-num-fix
RSHB:fix-logic-limitation
RSHB:projects-fix
RSHB:3-form-project
RSHB:project-add-year-handler
RSHB:projects-summary-handler
RSHB:AURORA-1247
RSHB:projects-handlers
RSHB:vsp-choose-form2-2
RSHB:directions-fix
RSHB:add-validation
RSHB:add-checkbox-export-vsp
RSHB:fix-update-column-config
RSHB:fix-editable-columns
RSHB:add-biome-front
RSHB:vsp-choose-form2
RSHB:export-form-4
RSHB:booking-fix
RSHB:fix-front-tables
RSHB:phase-directions
RSHB:AURORA-1225
RSHB:fix-mapping-form-2-oper
RSHB:AURORA-1076-fix
RSHB:fix-add-row-program-4-form
RSHB:form2-limit-migrations
RSHB:delete-projects
RSHB:AURORA-1076
RSHB:form-4-add-row
RSHB:fix-logs
RSHB:AURORA-1206
RSHB:AURORA-894
RSHB:add-line-log-hotfix
RSHB:form-export-fix
RSHB:form-4-sql
RSHB:table-optimization-fix
RSHB:header_forms
RSHB:form-4-expense-item-filters
RSHB:entity-type-hotfix
RSHB:form-3-phases-timezones
RSHB:form-4-handlers
RSHB:export-fix
RSHB:close-date-vsp-fix
RSHB:deleted-user-auth-fix
RSHB:smeta-fix
RSHB:front-fixes
RSHB:line_id_code_full
RSHB:line_id_code
RSHB:timezones
RSHB:filenames-fix
RSHB:AURORA-1174-73
RSHB:project-sheets
RSHB:AURORA-1166
RSHB:websocket-projects
RSHB:project-front
RSHB:form3-permissions
RSHB:location_from_to_placement_type
RSHB:fix-vsp-filters
RSHB:fix-tests-and-functions
RSHB:mig2-fix
RSHB:vsp_fixes
RSHB:fix-ssp-title
RSHB:AURORA-1148
RSHB:fix-vsp-form-edit
RSHB:sql-funcs2-fix
RSHB:AURORA-1132
RSHB:logs
RSHB:AURORA-1147
RSHB:export-optimization
RSHB:AURORA-1131
RSHB:sql-funcs-fix
RSHB:vsp-dropdown-form
RSHB:form_2-back
RSHB:migrations
RSHB:websocket-self-flag
RSHB:reload-fix
RSHB:test-stand-fix
RSHB:excel-empty-fix
RSHB:requirements-fix
RSHB:AURORA-1096-back
RSHB:AURORA-1098
RSHB:AURORA-1096
RSHB:ws-user-id-fix
RSHB:expense-item-handler
RSHB:fix-date-phase
RSHB:excel-fix
RSHB:vsp-edit-field-fix
RSHB:vsp-fix-back
RSHB:vsp-back
RSHB:create-form-back
RSHB:export-direction-fix
RSHB:change-role-fix
RSHB:org-unit-users-fix
RSHB:audit-fix
RSHB:org-archive
RSHB:del_row_fix
RSHB:websocket_locks
RSHB:new_line_id
RSHB:admin-back
RSHB:form-fix
RSHB:ws
RSHB:ssp-fix
RSHB:stages-back
RSHB:form_124_write
RSHB:form_124
RSHB:new-model
RSHB:test-tsygankov
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
No description provided.
Delete Branch "feat/270-aurora-1907-source-sheet"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #270.
Что сделано
Бэкенд (миграция
0053_form2_ahr_source_sheet.sql):v3.budget_line.source_sheet varchar NULL CHECK (... IN ('AHR_LIMIT','AHR_RENT','AHR_UTILITY','AHR_SECURITY'))+ ORM-поле вapi/src/db/models/budget_line.py.v3.form2_ahr_satellite_line_source; лимитные — строка с минимальнымidв группе (форма, статья, имя LEAF) помечаетсяAHR_LIMIT, остальные совпавшие по имени становятся ручными (список —RAISE NOTICE)._ensure_form2_ahr_detail_sync_line— ставитsource_sheetпри создании/привязке строки сателлита._ensure_form2_ahr_limit_sync_line— ищет строку средиsource_sheet='AHR_LIMIT'(а не по имени) — тот же класс бага, что чинил #265/AURORA-1909 для сателлитов, теперь для лимитов.is_form2_ahr_satellite_line,del_budget_line(guard на удаление),get_form2_ahr_satellite_delta— переведены на признак источника вместо сравнения имён.v3._form2_expense_item_has_limit(expense_item_id)— правило «у статьи есть лимит», используется и вheader.is_over_limit, и в агрегатах.v_form2_sheet_jsonb:header.source(AHR_LIMIT/AHR_RENT/AHR_UTILITY/AHR_SECURITY/MANUAL),header.is_over_limit;plan.limit_year/plan.over_limit_yearтолько на листеAHR, свёрнуты по дереву статей черезmv_expense_item_tree.desc_ids.plan.yearне меняется — сумма всех строк, включая ручные.Фронт:
AHR.js— колонки «В пределах лимита, год» / «Сверх лимита, год» после «План, год», нередактируемые.Cell.jsx— чип «сверх лимита» в ячейке наименования строки поheader.is_over_limit, без заливки строки цветом.export_mappings.py— те же два поля в выгрузке АХР (в общемFORM1_DEPTH_COLUMNS, см. рулинг R-3).Дефолты из тикета (применены как есть)
Рулинги, принятые самостоятельно (без обсуждения)
_ensure_form2_ahr_limit_sync_lineищет строку по(budget_form_id, expense_item_id, source_sheet='AHR_LIMIT', name)— имя оставлено в поиске, т.к. у одной статьи может быть несколько LEAF лимитов (пример — «Мобильная связь», 7 LEAF с разными именами на одномexpense_item_id); без ��мени строки лимитов были бы неотличимы друг от друга. При совпадении строки теперь дополнительно обновляетсяname/updated_at(раньше не обновлялось, т.к. совпадение и так шло по имени).get_form2_ahr_satellite_delta— доп. фильтрsource_sheet='AHR_LIMIT'добавлен только в ветку лимитов (защита от того самого бага с совпадением имени). Ветка сателлитов (аренда/коммуналка/охрана) не трогалась — там сопоставление и так однозначно идёт поsource_idчерезform2_ahr_satellite_line_source.export_mappings.py— колонкиlimit_year/over_limit_yearдобавлены в общийFORM1_DEPTH_COLUMNS(используется для OPER/AHR/CAP и для FORM_1, и для FORM_2 — отдельного columns_dict для FORM_2/AHR в экспорте не существует). Для сеток, где этих ключей в JSON нет (SMETA/CAP/OPER/FORM_1),normalized.get(key)отдаётNone→ ячейка пустая, падения экспорта нет. Ticket явно разрешал не углубляться в интеграцию с AURORA-1902.bf.form_type_code='FORM_2'— тот жеexpense_item_idиспользуется и в FORM_1/FORM_3/FORM_4 АХР (где лимитной синхронизации нет вовсе), совпадение имени там было бы случайным.is_form2_ahr_satellite_lineоборачиваетsource_sheet IS NOT NULLвCOALESCE(..., false)— чтобы сохранить поведение «строка/форма не найдена → false», как было с EXISTS в старой версии.expense_item_id=150, не 129, как в тексте 0003_initial_data.sql)."Директор"(без дефиса) — ровно то значение, которое_ensure_form2_ahr_limit_sync_lineдо фикса искало послеregexp_replaceLEAF"- Директор".Тесты
api/tests/integration/test_form2_ahr_satellite_integration.py— 6 новых тестов (4 через API, 2 прямым SQL на backfill-логику). Полный прогонpytest --init_dbна одноразовом Postgres 16 (Docker, порт 55433, неperf-pg): 237 passed, 3 failed (ровно те же 3 падения, что и на родительском коммите #266 без этой ветки — см. ниже), 4 skipped. Фронтовый unit-тест на чип не писался — логика тривиальна (одинisOverLimitбулев флаг), фокус был на backend TDD, как и разрешал тикет.Известные (не из этой серии) падения, не изменились относительно
ab765f0:test_db_functions_integration.py::test_backend_calls_form3_add_project_and_add_line_functionstest_export_service_query_params.py::test_export_full_form_ignores_non_applicable_params_for_other_sheetstest_export_service_query_params.py::test_export_form_payload_forwards_ignore_flag🤖 Generated with Claude Code
Миграция 0053: v3.budget_line.source_sheet (NULL | AHR_LIMIT | AHR_RENT | AHR_UTILITY | AHR_SECURITY) — явный признак источника строки вместо сопоставления по совпадению имени с LEAF limit_template. Backfill существующих строк: сателлиты — из v3.form2_ahr_satellite_line_source, лимитные — минимальный id в группе (форма, статья, имя LEAF), остальные совпавшие по имени становятся ручными (RAISE NOTICE со списком). _ensure_form2_ahr_limit_sync_line теперь ищет строку по source_sheet='AHR_LIMIT' (а не по имени) — тот же класс бага, что чинил #265/AURORA-1909 для сателлитов аренды/коммуналки/охраны, теперь для лимитов. is_form2_ahr_satellite_line, del_budget_line (guard на удаление) и get_form2_ahr_satellite_delta переведены на признак источника. Новая v3._form2_expense_item_has_limit выносит правило «у статьи есть лимит» в отдельную функцию. v_form2_sheet_jsonb: header.source ('AHR_LIMIT'/'AHR_RENT'/'AHR_UTILITY'/ 'AHR_SECURITY'/'MANUAL'), header.is_over_limit для ручных строк на статьях с лимитом; plan.limit_year/over_limit_year (только на листе AHR, свёрнуты по дереву статей через mv_expense_item_tree.desc_ids) — plan.year не меняется, остаётся суммой всех строк. Фронт: AHR.js — колонки «В пределах лимита, год»/«Сверх лимита, год» после «План, год» (нередактируемые — нет случая в v3._apply_form_cell); Cell.jsx — чип «сверх лимита» в ячейке наименования по header.is_over_limit, без заливки строки. export_mappings.py — те же два поля в экспорт АХР. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>Checkout
From your project repository, check out a new branch and test the changes.