125 Commits

Author SHA1 Message Date
Andrey Epifancev
9a151a19eb Merge remote-tracking branch 'origin/test' into feat/272-aurora-1887-ahr-hide-satellite-rows
# Conflicts:
#	web/src/components/RealtimeTable/RealtimeTable.jsx
#	web/src/components/RealtimeTable/utils/rowUtils.test.js
2026-11-02 21:50:17 +04:00
Andrey Epifancev
e755272787 Merge remote-tracking branch 'origin/test' into feat/289-aurora-1900-unit-vat-labels
# Conflicts:
#	web/src/components/RealtimeTable/constants/FORM_1/SMETA.js
2026-11-02 21:47:53 +04:00
aep
12aae02504 Merge pull request 'AURORA-1903: лист «Смета» — своя раскладка колонок для каждой формы' (#287) from feat/286-aurora-1903-smeta-export-layout into test 2026-11-02 20:36:59 +03:00
aep
296f868c4c Merge pull request 'AURORA-1907: признак источника строки АХР и раздельные суммы лимита/сверх лимита' (#271) from feat/270-aurora-1907-source-sheet into test 2026-11-02 20:32:54 +03:00
aep
69e333cf9f Merge pull request 'AURORA-1909: добавление записи на сателлите не захватывает ручную строку АХР' (#268) from feat/265-aurora-1909-ahr-manual-row-capture into test 2026-11-02 20:31:57 +03:00
aep
5317c04d3a Merge pull request 'AURORA-1906: колонка «СПОД» в листах аренды, коммуналки и охраны АХР' (#263) from feat/254-aurora-1906-spod-column into test 2026-11-02 20:30:23 +03:00
Andrey Epifancev
24ca4410f4 feat(labels): единые подписи «тыс. руб.» и НДС на экране и в выгрузке (AURORA-1900)
Экран: {unit}-плейсхолдер (formatHeaderUnit, переиспользует разрядность из
useDenomination/moneyUtils AURORA-1899) в TableHead.jsx, CollapsibleTree.jsx,
templateColumns.js; литерал «тыс. руб.» → {unit} в заголовках FORM_1/FORM_2/
FORM_4/PROJECT (кроме AHR_LIMIT.js — рублёвое исключение не трогаем) и в
своих колонках Свод1/Свод2 (SummaryTable.scaleColumns, Svod2Page.
scaleNumericColumns). Текст НДС на экране не менялся.

Выгрузка: «с учетом НДC» (латинская C, 96 мест в FORM1_DEPTH_COLUMNS и
производных FORM4_*) → плейсхолдер {vat}/{vat_plan}, резолвится по листу
через render_column_years(..., extra=...) — Ф.1 OPER/CAP «с учётом НДС»,
Ф.1 AHR и все листы Ф.4 «без НДС» (соответствует экрану). SMETA_COLUMNS —
«, тыс. руб.» у сумм. Своды — строка метаданных «Единица: тыс. руб.».

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-01 20:16:27 +04:00
Andrey Epifancev
72f48cc559 fix(export): лист "Смета" выгружается по раскладке экрана каждой формы (AURORA-1903)
До этой правки лист "Смета" всех форм выгружался одной плоской
раскладкой SMETA_COLUMNS (41 колонка) — для FORM_2/FORM_4 в выгрузке
были лишние колонки другого направления (поддержка/развитие), которых
нет на экране. Добавлена SMETA_COLUMNS_BY_FORM{"FORM_1","FORM_2","FORM_4"}
с раскладкой колонок строго в порядке экрана каждой формы;
_create_xlsxwriter_sheet_writers теперь выбирает нужный список по
form_type_code. SMETA_COLUMNS остаётся алиасом на FORM_1-раскладку для
обратной совместимости (неиспользуемый openpyxl-словарь, старый тест).

Также TabularSheetWriter.write и XlsxTabularSheetWriter.write теперь
пропускают служебную строку META (как уже делают depth-писатели) —
раньше она давала пустую вторую строку на листе "Смета".

На экране FORM_1/SMETA.js добавлены "Утверждено ИТОГО Год" (Z) и
"Факт ИТОГО Год" (AL) — SQL (v_form_view) всегда их отдавал и
выгрузка Excel их писала, но экран их терял.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-01 16:01:25 +04:00
Andrey Epifancev
d5cbd151c5 fix(tests): согласовать AURORA-1844/1846/1850 с null-strip из AURORA-1848
AURORA-1848 (#239/#242) убрал null-поля из GET листа/сводов (jsonb_strip_nulls),
оставив PATCH как раньше (задокументированный breaking-change в PR, не баг).
После слияния веток в test это разошлось с тестами, написанными до #239/#242:

- sheet_contract.assert_patch_rows_match_sheet сравнивал PATCH и GET побайтно —
  добавлен strip_nulls() на стороне PATCH перед сравнением.
- test_form4_sheet_sums.py сравнивал ответ API с "сырым" v3.jsonb_sum (с null-полями)
  и ожидал явный null в некоторых полях ответа — эталон теперь тоже прогоняется через
  strip_nulls, а прямые ожидания null заменены на .get(...) is None / отсутствие ключа.

Без изменений контракта API: PATCH продолжает отдавать null явно, как в #242.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-01 12:39:14 +04:00
Andrey Epifancev
7514ac9803 fix(realtime): getDataRowId возвращает null вместо undefined, тесты M-8/M-9
После jsonb_strip_nulls у групп/позиций нет ключа line_id, getDataRowId
возвращал undefined, и row_id в сообщении удаления сериализовался в {}
(KeyError на сервере). Возвращаем null, как до фазы B.
Добавлены тесты updateCells (глубокое отсутствие блока, два обновления в батче)
и сверка jsonb_strip_nulls с _strip_nulls.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:14:49 +04:00
Andrey Epifancev
a34ccdcb9c perf(api): лист и своды без null-полей в data (jsonb_strip_nulls)
row_json_select(strip_nulls) оборачивает data в jsonb_strip_nulls внутри json_build_object;
флаг пробрасывается через get_json/get_svod1_json/get_svod2_json, роутеры листа и сводов
включают его. Проекты, PATCH/POST/DELETE не затронуты.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:14:49 +04:00
aep
9c7a5a4575 Merge pull request 'AURORA-1846: FORM_4 суммы листа без рекурсивного jsonb_sum' (#232) from feat/216-aurora-1846-form4-sheet-sum into test 2026-11-01 11:04:08 +03:00
Andrey Epifancev
b267905d09 test(sheet): ничья ключа сортировки по-настоящему, F1-AHR-plan, комментарий 0051 (AURORA-1850)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:47:27 +04:00
Andrey Epifancev
e396b5a053 test(sheet): защита правки 0037 после 0051 (AURORA-1850)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:47:27 +04:00
Andrey Epifancev
1d18cf812f perf(sql): jit = off на построителях и пути правки (AURORA-1850)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:47:27 +04:00
Andrey Epifancev
17f3de602a test(sheet): усиление красных тестов эквивалентности по ревью Task 2 (AURORA-1850)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:47:27 +04:00
Andrey Epifancev
5b6c7e244e test(sheet): эквивалентность ответа на правку и полной сборки — красные тесты (AURORA-1850)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 10:47:27 +04:00
aep
f2c503c292 Merge pull request 'AURORA-1844: upd_form_cells возвращает строки целиком' (#231) from feat/215-aurora-1844-upd-form-cells-full-rows into test 2026-11-01 09:46:45 +03:00
aep
37bb563f5d Merge pull request 'AURORA-1831: гонка technical_number при параллельном POST /projects' (#229) from feat/207-aurora-1831-project-tn-race into test 2026-11-01 09:45:32 +03:00
aep
15c6402ad3 Merge pull request 'AURORA-1832: aware-даты этапов форм и проектов (часовой пояс)' (#228) from feat/208-aurora-1832-phase-dates-tz into test 2026-11-01 09:43:46 +03:00
aep
f1b4f6d306 Merge pull request 'AURORA-1848: тяжёлые GET — готовый JSON из Postgres без pydantic-модели на строку (A)' (#239) from feat/233-aurora-1848-sheet-json-no-pydantic into test 2026-11-01 09:42:06 +03:00
aep
dc82239770 Merge pull request 'AURORA-1845: кэш user/формы на время WS-соединения' (#238) from feat/237-aurora-1845-ws-connection-cache into test 2026-11-01 09:41:43 +03:00
aep
8b081a4b42 Merge pull request 'AURORA-1833: явно ставить greenlet в dev-окружении' (#225) from feat/209-aurora-1833-greenlet-dev into test 2026-11-01 09:39:59 +03:00
aep
6ff979ae57 Merge pull request 'AURORA-1830: /users/me не падает на email .local' (#224) from feat/206-aurora-1830-users-me-local-email into test 2026-11-01 09:39:44 +03:00
Andrey Epifancev
234103606b feat(form2): скрыть сателлитные строки на листе АХР и заблокировать добавление для аренды/коммуналки/охраны (AURORA-1887)
Упрощённый дизайн (согласован в чате 2026-10-31, расходится с архитектурным
предложением из тикета): без слияния budget_line, без миграции данных, без
изменения протокола WS, без изменения v_svod2_rf.

- v3.v_form2_sheet_jsonb (0054): при p_sheet='AHR' не возвращает INPUT-строки
  с budget_line.source_sheet IN ('AHR_LIMIT','AHR_RENT','AHR_UTILITY',
  'AHR_SECURITY'); ручные строки (включая «сверх лимита», AURORA-1907)
  остаются видимыми. Листы-источники не затронуты. Суммы на заголовках статей
  считаются независимо от видимости строк — не меняются.
- header.can_add_row (новое поле, только p_sheet='AHR'): false для статей
  аренды/коммуналки/охраны (v3._form2_satellite_expense_item, новый helper),
  true для лимитных и обычных статей. Фронт (RealtimeTable.jsx handleAddRow,
  utils/rowUtils.js canAddRowForHeader) блокирует «Добавить строку» по этому
  флагу — тот же паттерн, что у FormsNoCanAddRow/isVspAdditionRow (без
  серверной валидации в add_budget_line).
- Обновлены тесты, которые проверяли суммы/источник через теперь скрытые
  INPUT-строки на AHR (test_form2_ahr_limit.py,
  test_form2_ahr_satellite_spod_integration.py,
  test_form2_ahr_satellite_integration.py) — сравнение переведено на
  заголовок статьи (до/после патча) и на лист-источник.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-31 21:59:04 +04:00
Andrey Epifancev
fe9dfbc7e1 feat(form2): признак источника строки АХР и раздельные суммы лимита/сверх лимита (AURORA-1907)
Миграция 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>
2026-10-31 17:54:55 +04:00
Andrey Epifancev
ab765f028d fix(form2): лимиты АХР — годовые нормативы делятся на 4, сумма без НДС, тыс. руб. в АХР
AURORA-1897: лист «АХР лимиты» формы 2 дублировал годовой норматив ДМС/оргтехники
в каждом квартале вместо деления на 4, считал сумму от лимита с НДС (смета
ведётся без НДС) и переносил рубли в план АХР, где всё остальное в тыс. руб.

Миграция 0052_form2_ahr_limit_period_vat_units:
- v3.limit_template.period (YEAR/QUARTER/MONTH) + точечные правки справочника
  (id 24/25 ДМС и id 13-15 принтеры/МФУ/копиры — YEAR; id 7/8 SIM-карты —
  заполнен limit_without_vat; id 21 — unit по аналогии с бумагой).
- v3._form2_ahr_limit_amount(period, limit, qty) — рубли без НДС, без
  проверки по названию; старая 4-арг. сигнатура удалена.
- v3.v_form2_view (ветка AHR_LIMIT), v3.sync_form2_ahr_satellite_lines(_line)
  пересозданы: amount/plan считаются от limit_without_vat, план АХР делится
  на 1000, добавлены amount_year и строка «Итого» (id=0, row_type ROOT).
- v3._limit_template_path_set дописывает id=0 в path-set, чтобы «Итого»
  попадала в diff PATCH-ответа.
- Пересинхронизированы все существующие формы 2.

Ветки аренды/коммуналки/охраны и add_budget_line (AURORA-1887/1909) не тронуты.

Тесты: api/tests/integration/test_form2_ahr_limit.py (7 тестов, числа из
тикета: id24 qty10→69645/69.645, id3→2000/2.0, id7→7500/7.5, id13→6471.875/
6.471875, id17→7500/7.5, «Итого», регрессия АХР_RENT без деления).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-31 15:35:23 +04:00
Andrey Epifancev
91cbe99c32 fix(form2): добавление записи на сателлите АХР не захватывает ручную строку
v3.add_budget_line (ветка сателлитов AHR_RENT/AHR_UTILITY/AHR_SECURITY)
искала любую существующую строку статьи без ORDER BY и без исключения
ручных/уже привязанных строк, и переиспользовала её как заготовку для
новой записи. Если у статьи ещё не было строк в
v3.form2_ahr_satellite_line_source (типично — первая запись при наличии
ручной строки той же статьи), sync переименовывал и перезаписывал план/факт
чужой ручной строки, блокируя её для правки.

Теперь для каждой новой записи сателлита всегда создаётся отдельная
пустая строка-заготовка — sync забирает её как строку именно этой записи.
Заодно удалён мёртвый код (_ensure_form2_ahr_sync_line,
_upsert_form2_ahr_sync_values), не имевший вызывающих мест.

AURORA-1907 (лимитная часть) и AURORA-1887 (статьи 314/24/779 в коде) —
отдельные задачи, не затронуты.

Closes #265.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-31 15:07:44 +04:00
Andrey Epifancev
a5ffd476a6 fix(tests): реальный прогон интеграционных тестов СПОД против Postgres
Прогнал api/tests/integration/test_form2_ahr_satellite_spod_integration.py
против живого Postgres (perf/perf/perf на localhost:55432, БД dfip_1906,
alembic upgrade head + фикстура) — нашёл и поправил два бага самого теста
(фичу/миграцию не трогал):

- _find_row не учитывал служебную META-строку (editable/role/user_id без
  id/header), которую v3.v_form_view добавляет первой в любой лист —
  KeyError: 'id' на первой же выборке. Теперь ищет только среди INPUT-строк.
- test_satellite_spod_phase_gates_non_admin_user делал один тест из
  "запрет без fact_q4.spod → добавили ключ → разрешено": неадминский
  403/400 от isp1 внутри теста вызывает db_ref.rollback() в
  tests/integration/conftest.py (per-request откат на ошибке), который
  стирает все несохранённые изменения этого же теста — включая только
  что созданные строку сателлита и form_phase. Разбил на два независимых
  теста (test_satellite_spod_rejected_before_phase_includes_spod_column /
  test_satellite_spod_allowed_once_phase_includes_spod_column), в каждом
  ровно один запрос, которому разрешено провалиться.

pytest tests/integration — 157 passed, 1 failed (pre-existing,
не связан: test_backend_calls_form3_add_project_and_add_line_functions,
FORM_3/add_project, 400 на /api/v1/projects/.../report/.../line), 4 skipped.
Новый файл — 15/15.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-31 00:41:10 +04:00
Andrey Epifancev
d41668dc27 feat(form2): колонка «СПОД» в сателлитах АХР (аренда/коммуналка/охрана)
Добавлен столбец «СПОД» между «Декабрь» и «Итог IV кв.» на листах
AHR_RENT/AHR_UTILITY/AHR_SECURITY формы 2, с переносом значения в
budget_line_quarter.actual_spod синхронизируемой строки АХР (Support)
и, через уже существующую логику, в итог 4 кв. и года АХР/Смет/сводов.

- rent_detail/utility_detail/security_detail: колонка actual_spod
  (ALTER TABLE + ORM).
- v3.v_form2_view: fact_q4.spod и fact_q4.total с учётом spod в ветках
  AHR_RENT/AHR_UTILITY/AHR_SECURITY.
- v3._apply_form_cell: fact_q4.spod разрешён как обычное поле месяца.
- v3._upsert_form2_ahr_detail_sync_values: DROP+CREATE с новым
  параметром p_actual_spod (DROP обязателен из-за неоднозначности
  перегрузки с DEFAULT).
- v3.sync_form2_ahr_satellite_lines/line: actual_spod передаётся из
  rd/ud/sd в апсерт.
- v3.v_svod2_go: строка аренды также считается заполненной по
  actual_spod.
- Data-миграция: 'fact_q4.spod' добавлен в column_keys этапов, где уже
  есть 'fact_q4.dec' (phase_template/form_phase), идемпотентно.
- Тело CREATE OR REPLACE для v_form2_view/sync_form2_ahr_satellite_*
  собрано вручную по миграциям 0033/0034 + regexp-патчам из 0037
  (pg_get_functiondef на живой БД недоступен в этой среде — см.
  Rulings в PR).

Тесты: node --test на новых accessorKey в конфигах фронта + unit-тест
на 0049/0050 (v_svod2_go теперь засчитывает actual_spod для аренды).
Интеграционные тесты добавлены, но не выполнены — нет доступа к
Postgres в этой рабочей среде (см. Rulings в PR).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-31 00:24:56 +04:00
Andrey Epifancev
05fbfd1e1d perf(form4): jit=off на v_form4_sheet_jsonb — компиляция JIT дороже выполнения
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-29 12:11:25 +04:00
Andrey Epifancev
b612178b12 fix(tests): тесты тяжёлых GET — непустые данные свода 2, gzip, правки докстрингов
Фикстура свода 2 достроена до 6 строк на GO и RF по двум орг. единицам с разными section_code;
все случаи SVOD2_CASES проверяют непустоту. Тест rf-rollup переименован (фиксирует существующий дефект),
добавлен тест gzip, в api_split.py оставлены только GET-места.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:43:31 +04:00
Andrey Epifancev
604e277371 perf(api): отчёты и сводные проектов отдают готовый JSON из Postgres
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:24:14 +04:00
Andrey Epifancev
ca7160124a perf(api): GET сводов 1 и 2 отдают готовый JSON из Postgres
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:16:36 +04:00
Andrey Epifancev
d8dba2f7be perf(api): GET листа отдаёт готовый JSON из Postgres без SheetResponse на строку
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:12:09 +04:00
Andrey Epifancev
7094fe839f perf(api): хелпер ответа из готовых JSON-строк и SQL-выражение строки
Добавлены list_json_response (обёртка BaseListResponse из готовых строк),
ROW_COLUMNS, row_json_select и fetch_row_texts для тяжёлых GET (AURORA-1848).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:07:40 +04:00
Andrey Epifancev
0175759f95 test(api): фикстура db_session и снимок схемы OpenAPI тяжёлых GET
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 21:06:16 +04:00
Andrey Epifancev
4dae72da2b test(ws): кэш соединения - unit и интеграционный через websocket_connect
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 20:17:56 +04:00
Andrey Epifancev
55ba4e7e96 test(form4): суммы ROOT/GROUP/ITEM листа CAP против v3.jsonb_sum и Python, фикстура db_session
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:33:58 +04:00
Andrey Epifancev
f0cac30622 test(sheet): контрактный тест ответа PATCH /cell с полными строками (AURORA-1844)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:18:07 +04:00
Andrey Epifancev
663f45ee04 test(projects): гонка technical_number и переполнение счётчика (AURORA-1831)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:14:33 +04:00
Andrey Epifancev
d73333705c test(stages): aware-даты этапов форм и проектов
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:13:13 +04:00
Andrey Epifancev
b0dcc0b0f5 fix(deps): явно ставить greenlet в dev-окружении через sqlalchemy[asyncio]
SQLAlchemy не объявляет greenlet без extra asyncio. На arm64 (macOS)
и на Python >= 3.13 greenlet не ставится, и async-движок падает с
"the greenlet library is required". Тест фиксирует наличие greenlet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:11:10 +04:00
Andrey Epifancev
2dc9b4df03 fix(users): выходные схемы пользователя без входных ограничений (/users/me 500 на .local)
UserInDB наследует новую UserReadBase (email/username/full_name без
валидации формата). Вход (UserBase/UserCreate/UserUpdate) не менялся.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:11:06 +04:00
Andrey Epifancev
5e7ac886aa test(alembic): регрессия на подзапросы в FROM без алиаса (PostgreSQL 15)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-28 18:10:13 +04:00
744c8962cd Merge pull request 'svod2-filter-fix2: если заполнен только всп не берем в свод 2' (#197) from svod2-filter-fix2 into test
Reviewed-on: #197
2026-10-21 17:33:12 +03:00
8d6e7ba51b svod2-filter-fix2: если заполнен только всп не берем в свод 2 2026-10-21 17:31:34 +03:00
18b834e1f8 Merge pull request 'indent-export: отсупы в экспорте по глубине вложенности' (#196) from indent-export into test
Reviewed-on: #196
2026-10-21 15:48:42 +03:00
669e352980 indent-export: отсупы в экспорте по глубине вложенности 2026-10-21 15:46:08 +03:00
f92c0e8d32 svod2-filter-fix: строки совсем без значений не попадают в свод 2 2026-10-21 15:38:48 +03:00