272 Commits

Author SHA1 Message Date
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
Andrey Epifancev
67c192a2e0 Merge remote-tracking branch 'origin/test' into feat/285-aurora-1899-denomination-base-thousand
# Conflicts:
#	web/src/components/RealtimeTable/Cell/Cell/Cell.jsx
2026-11-02 21:45:04 +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
5fe1264064 Merge pull request 'AURORA-1894: красная рамка у ошибки ячейки, тост без Server error:undefined' (#277) from feat/275-aurora-1894-error-border-toast into test 2026-11-02 20:34:38 +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
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
733d7a9036 fix(denomination): база разрядности — тыс. руб., масштабировать только денежные колонки
Селектор разрядности (AURORA-1650) считал базой рубли, хотя в базе суммы
хранятся в тыс. руб. (формы 1/4, сателлиты формы 2, лимитные строки АХР
после AURORA-1897). По умолчанию стояло «в руб.», и тысячи показывались
под видом рублей; при выборе «в тыс. руб.» значения делились ещё раз.
Делитель также применялся к количествам, площади, ставке НДС, курсу,
кодам и ID — не только к деньгам. Редактор ячейки не учитывал разрядность.

- web/src/components/RealtimeTable/utils/moneyUtils.js — новый модуль:
  UNIT_IN_RUB, getDisplayFactor(baseUnit, denomination), getMoneyUnit
  (денежная единица колонки по accessorKey/sheetName, с явным
  columnDef.moneyUnit как переопределением), TEXT_COLUMN_IDS (перенесён
  из Cell.jsx), resolveDenomination/DEFAULT_DENOMINATION, AHR_LIMIT_SHEET.
  Модуль не импортирует конфиги форм — работает под node --test.
- useDenomination.js — значение по умолчанию 'thousand', ключ хранения
  со суффиксом _denomination_v2 (старые 'rub'/'thousand' больше не
  читаются со старым смыслом); getDenominationDivisor убран.
- tableColumns.jsx/Cell.jsx — displayDivisor заменён на displayFactor
  (умножение, не деление), множитель считается на колонку через
  getMoneyUnit/getDisplayFactor с учётом sheetName; isEditable запрещает
  редактирование денежной ячейки, если разрядность не базовая; на листе
  AHR_LIMIT множитель всегда 1 (значения в рублях, как есть).
- SettingPanel.jsx — селектор скрыт на листе AHR_LIMIT, рядом с ним
  подсказка «Ввод сумм — в тыс. руб.».
- SvodPage/Svod2Page/ProjectSummariesPage — масштабирование по
  meta.money вместо regex по id/блок-листа текстовых id; построители
  колонок проставляют meta.money на денежных метриках.
- DenominationSelect.jsx — «в млн руб.», «в млрд руб.» без точки.

Тесты: web/src/components/RealtimeTable/utils/moneyUtils.test.js
(node --test), полный набор web/src/components/RealtimeTable/utils —
52/52 зелёных. npm run build проходит.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-01 16:08:20 +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
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
c7c679851d fix(realtime): пустая правка уходит как value: null, а не без ключа (AURORA-1848)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:14:49 +04:00
Andrey Epifancev
be8d41ccb5 test(realtime): правка соавтора по ключу, которого нет в строке (AURORA-1848)
Четыре теста updateCells: вставка отсутствующего блока и поля,
явная запись null, вставка отсутствующего скалярного ключа data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 12:14:49 +04:00
Andrey Epifancev
83cb364a9e fix(realtime): красная рамка у ошибки ячейки, тост без Server error:undefined (AURORA-1894)
Cell.jsx: порядок спреда стилей — base → editable/not-editable → locked →
invalid (INVALID_STYLES последним), чтобы красная рамка 2px не перетиралась
EDITABLE_STYLES у вводимых ячеек с ошибкой.

utils/wsErrorUtils.js: getWsErrorMessage(error) — строка возвращается как
есть, объект берёт message || detail, известные технические префиксы
(computed_field:, role_not_allowed:, window_closed:, org_not_assigned)
заменяются понятным текстом, прочее отдаётся без "Server error:".

RealtimeContext.js: toast.error(getWsErrorMessage(data.error)) вместо
`Server error:${data.error.message}` || '', которое всегда давало undefined
для ошибок-строк (|| не срабатывает на непустой строке).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-11-01 12:10:16 +04:00
aep
26ae77878b Merge pull request 'AURORA-1837: статичные стили ячеек в CSS, overscan' (#230) from feat/226-aurora-1837-cell-styles-css into test 2026-11-01 11:05:50 +03:00
aep
cda8f12492 Merge pull request 'AURORA-1838: updateCells без клонирования всего дерева' (#223) from feat/212-aurora-1838-ws-immutable-update into test 2026-11-01 09:38:39 +03:00
aep
1ece2f3c08 Merge pull request 'AURORA-1836: фиксированная высота строк вместо measureElement' (#222) from feat/211-aurora-1836-row-measure into test 2026-11-01 09:37:38 +03: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
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
7b67740029 fix(dict-vsp): заголовок «Действия» на одной линии с остальными в grid-раскладке
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-29 12:23:02 +04:00
Andrey Epifancev
bf64fa0dc6 fix(dict-vsp): ширины колонок как в test — grid-раскладка не должна менять вид справочника
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:10:47 +04:00
Andrey Epifancev
f7e553a7ab style(table): переименовать параметр escape в activeCellCss (biome)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:14:53 +04:00
Andrey Epifancev
21aded26cc perf(table): статичные стили ячеек в CSS контейнера, overscan строк 2 и колонок 3
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:14:38 +04:00
Andrey Epifancev
4393e964f4 perf(realtime): убрать console.log каждого WebSocket-сообщения
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:10:30 +04:00
Andrey Epifancev
17dddc21d3 perf(realtime): updateCells без structuredClone и мутации входа
Копируются только строки на пути к затронутой, остальные сохраняют идентичность;
без изменений возвращается тот же data. Отсутствующие в row.data ключи теперь
вставляются (нужно для AURORA-1844/1848). Тесты с паритетом к прежней реализации.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-28 18:10:30 +04:00
Andrey Epifancev
12a315b04a perf(table): фиксированная высота строк вместо measureElement (лист, свод 1, свод 2)
Высота строки и ячейки задана явно в rem, виртуализатор не читает offsetHeight.
Мёртвая muiTableRowProps удалена. Overscan строк свода 2: 8 -> 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:10:21 +04:00
Andrey Epifancev
bdb00afc5a test(table): хелпер createFixedRowVirtualizerOptions без чтения layout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:10:21 +04:00
Andrey Epifancev
b0de763259 perf(dict-vsp): виртуализация строк, состояние модалок вынесено из таблицы
Модалки в DictVspModals (forwardRef), таблица в memo со стабильными колбэками,
enableRowVirtualization, size/minSize/maxSize колонок выверены под grid-раскладку.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:09:52 +04:00
Andrey Epifancev
3ab229f6f8 test(dict-vsp): фильтрация ВСП по ССП вынесена в чистую функцию
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-28 18:09:52 +04:00
PotapovaA
7174703149 изменение дублей accessorKey 2026-10-20 16:21:42 +03:00
PotapovaA
bce897f4ed правки 2026-10-16 14:55:58 +03:00
PotapovaA
6c3cd5b2e0 добавление селекта для изменения разрядности в твблицах 2026-10-16 14:41:19 +03:00
PotapovaA
f3539a5f36 новые своды для проектов 2026-10-01 18:20:30 +03:00
PotapovaA
b8632b445d Merge remote-tracking branch 'origin/test' into add-svod-projects 2026-10-01 15:43:47 +03:00
PotapovaA
633c36787d своды для проектов 2026-10-01 15:43:26 +03:00
172b343c69 export-optimize-refresh: очередь загрузки при экспорте 2026-09-30 20:40:21 +03:00
341e8b3936 last-column: Колонка Сумма оплаты структуры формы 4 2026-09-30 14:02:41 +03:00
PotapovaA
02a24954e5 исправила цвета колонок 2026-09-29 15:48:11 +03:00
PotapovaA
253e5d7c82 удаление задач 2026-09-28 19:12:03 +03:00
PotapovaA
056d00b2b4 Merge branch 'test' into ui-tasks 2026-09-28 17:38:04 +03:00
18faf6a724 svod-fix: свод 2 из формы 2, новый свод 1 для формы 3 2026-09-28 17:01:07 +03:00
1e02b0ca61 fix-columns: добавил комментарий, строки из Лимита не удаляются 2026-09-28 13:19:26 +03:00
PotapovaA
d5728c8e08 изменен список задач + удалила не используемые файлы 2026-09-25 14:45:27 +03:00
d6da54ecf4 form3-expense: добавил новые статьи в форму 3, возможность удаления задач 2026-09-25 14:20:04 +03:00
PotapovaA
bc4fd92791 правки версий библиотек 2026-09-24 16:29:27 +03:00
e01c0c105f Merge pull request 'add-columns-spod-4-form' (#176) from add-columns-spod-4-form into test
Reviewed-on: #176
2026-09-24 15:11:46 +03:00
PotapovaA
b4ba58a8d8 переезд на новую версию либы 2026-09-24 15:11:09 +03:00
PotapovaA
15ac95f7d7 добавила колонки + переехала на @babel/traverse@^7.28.5 2026-09-24 15:10:52 +03:00
adfc2dda81 form3-pages: новая разметка третьей формы, сводные отчеты по третьей форме на бэке 2026-09-24 12:28:27 +03:00
PotapovaA
f87098f11e исправила цвета, сделала поярче breadcrumbs и исправила поиск в этапах 2026-09-18 16:14:52 +03:00
9ea88f99e9 Merge pull request 'fixes-form: добавил новые статьи' (#164) from fixes-form into test
Reviewed-on: #164
2026-09-16 15:44:03 +03:00