Дизайн экрана «Таблица корректировки» (#206)
OpenSpec change corrections-table-ui: proposal, design, спека corrections-table-ui и дельта intercompany-matrix-ui (вкладка доступна). AURORA-1541. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ddf69d42c1
commit
31fb404b47
2
openspec/changes/corrections-table-ui/.openspec.yaml
Normal file
2
openspec/changes/corrections-table-ui/.openspec.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-10-28
|
||||
181
openspec/changes/corrections-table-ui/design.md
Normal file
181
openspec/changes/corrections-table-ui/design.md
Normal file
@ -0,0 +1,181 @@
|
||||
# Дизайн: экран «Таблица корректировки» (AURORA-1541, arm-core #206)
|
||||
|
||||
## Зачем
|
||||
|
||||
Кредитный аналитик на шаге консолидации видит, где внутригрупповые обороты двух компаний не сошлись, разбирается, из каких
|
||||
строк ОСВ сложилась каждая сторона, переносит строки между правилами и вносит корректировку — сколько и из каких статей ББ
|
||||
исключить. Без экрана корректировки ВГО делаются только вне системы, и тестирование корректировок (AURORA-1542, с 03.11)
|
||||
начать нельзя.
|
||||
|
||||
## Что считается готовым (слова владельца, 28.10.2026)
|
||||
|
||||
- К сроку 02.11 — **рабочий экран на настоящем API**, не демо на моках. Если бэкенд (AURORA-1540) или аналитика не успевают —
|
||||
мы сами помогаем ребятам доделать.
|
||||
- Моки нужны, чтобы фронт не стоял, пока нет API, а не как результат.
|
||||
|
||||
**Объём плана — только `web/`.** Бэкенд (DBML, `vgo_assignment`, разнесение, эндпоинты, аудит) — AURORA-1540 Цыганкова;
|
||||
помогаем ему на ревью его PR, а не задачами этого плана. Последняя задача плана — подключение к настоящему API, когда 1540
|
||||
слит: флаг `REACT_APP_CORRECTIONS_MOCK` выключается, если эндпоинты есть в `main`, вкладка открывается на стенде на
|
||||
реальной версии и проходит сценарии спеки; расхождения ответа с контрактом правятся в той ветке, где ошибка (фейк или
|
||||
бэкенд). Сверяем фейк с реальным ответом мы (владелец / этот агент) при подключении.
|
||||
|
||||
## Источники и их вес
|
||||
|
||||
1. Аналитика Лысенко — DOC-272613, ответы 1–7 (AURORA-1395, 27.10), DOC-274230. **Приоритетна над нашими правилами и
|
||||
черновиками** (решение владельца 28.10).
|
||||
2. Дизайн от 23.10.2026 — `ДКБ_таблица_корректировок_23_10_26_1.html` (вложение к DOC-272613; в корне workspace). Как лежат
|
||||
строки в дизайне — визуализация; логика — по аналитике.
|
||||
3. ТЗ 6.8 / Прил. 9 — ниже аналитики, иногда игнорируется.
|
||||
4. Контракт API — `../docs/dev/api-contract-corrections.md` и `.openapi.yaml` (docs #183, вложение в AURORA-1540).
|
||||
|
||||
Открытые вопросы аналитику (комментарий `[design-23-10-check]` в AURORA-1395, п. 1–12 + 3 по ТЗ; в AURORA-1396 — ОФР) не
|
||||
блокируют работу: зависящие места сделаны так, чтобы ответ менял поведение точечно.
|
||||
|
||||
## Цели
|
||||
|
||||
- Вкладка «Таблица корректировки» страницы отчёта версии, по виду — как дизайн 23.10.
|
||||
- Таблица агрегатов с раскрытием до строк ОСВ, нераспределённые строки, итоги, фильтры, пресеты по правилам, единицы,
|
||||
настройка колонок, экспорт, полный экран.
|
||||
- Окно «Корректировка операции» агрегата: строки сторон, распределение по статьям, контроль, комментарий, сохранение.
|
||||
- Решения по строкам: флажок «Учитывать в КФО», отнести / перенести / убрать / вернуть к автоматике.
|
||||
- Отмена корректировки агрегата.
|
||||
- Только чтение, когда сервер так говорит (`editable = false`).
|
||||
|
||||
## Не цели
|
||||
|
||||
- Бэкенд и DBML (AURORA-1540), правила §8 в `05-domain-rules.md`.
|
||||
- ОФР (нет в дизайне; AURORA-1396), импорт xlsx (ТЗ 6.8, ждёт ответа).
|
||||
- Корректировка строки ОСВ и нераспределённой строки (аналитика: только агрегат; ждёт п. 2).
|
||||
- Переход из шахматки с фокусом на паре (AURORA-1653), учёт корректировок в шахматке (AURORA-1643).
|
||||
|
||||
## Анти-цели (провал, даже если «работает»)
|
||||
|
||||
- Фронт сам считает разнесение строк, отклонения, порог 5 % или статусы агрегата — это делает сервер; фронт только
|
||||
показывает, форматирует и суммирует видимые строки для «Итого».
|
||||
- Деньги через `number`/`float` с потерей копеек. Суммы — строки контракта, сложение — точное десятичное.
|
||||
- Экран, в котором можно что-то нажать и молча потерять изменения окна корректировки.
|
||||
- Кнопки правки у версии, которую сервер считает нередактируемой.
|
||||
|
||||
## Ограничения
|
||||
|
||||
- `web/` arm-core: React 18 + TS strict, antd 6, react-router 7, biome (140, одинарные кавычки), vitest.
|
||||
- Деньги в API — рубли строками с двумя знаками; показ в руб. / тыс. руб. и 0–2 знака — как в шахматке.
|
||||
- Состояние экрана — локальные хуки (стор Redux пуст по соглашению шаблона).
|
||||
- Пользователь слаб во фронте — решения в PR объясняются простыми словами.
|
||||
- Каждый экран сверяется с дизайном в Playwright и проходится руками до сдачи.
|
||||
|
||||
## Как устроено
|
||||
|
||||
### Данные
|
||||
|
||||
- `GET …/corrections?statement_type=balance` — одна загрузка всей таблицы; фильтры, сортировка, «Итого» — на клиенте.
|
||||
- Правки: `PUT …/aggregates/{rule}/{c1}/{c2}` (сохранить), `POST …/revoke`, `POST …/allocations` (решение по строке, ответ —
|
||||
вся таблица), `GET …/export`.
|
||||
- Клиент — `web/src/services/api/corrections.ts` поверх `api/client.ts`. При `REACT_APP_CORRECTIONS_MOCK=true` те же функции
|
||||
отвечают из фейка контракта в памяти (данные — из дизайна 23.10, с проверками контракта: обязательный комментарий,
|
||||
`expected_version_no`, применимость правила). Флаг по умолчанию выключен; в production-сборке фейк не используется.
|
||||
|
||||
### Таблица
|
||||
|
||||
Колонки как в дизайне: «Учитывать в КФО»; Дебет — ЮЛ, Строка баланса, Счёт, Сумма; Кредит — то же; Контроль —
|
||||
Отклонение %, Отклонение сумма; Корректировка — Строка баланса, Сумма (Дт), Строка баланса, Сумма (Кт), Комментарий;
|
||||
колонка действий.
|
||||
|
||||
- **Строка агрегата.** Суммы сторон, счета (`accounts`), отклонение. Процент и сумма отклонения красные при
|
||||
`exceeds_threshold`. Корректировка — статьи и суммы `correction.debit` / `credit` (несколько статей стороны — по строке на
|
||||
статью в ячейке), комментарий. Действия: «Корректировать» (окно), меню «…» — «Отменить корректировку» (если есть).
|
||||
`composition_changed` — подсветка строки и значок с подсказкой «Состав изменился после корректировки».
|
||||
`correction.status = DRAFT` — пометка «черновик» у корректировки.
|
||||
- **Раскрытие.** Под агрегатом — его строки ОСВ (`side_1.entries`, затем `side_2.entries`): строка стороны 1 заполняет блок
|
||||
«Дебет», стороны 2 — «Кредит», остальные ячейки пустые (DOC-272613 п. 3.4; пары строк из дизайна не строим). У строки —
|
||||
флажок «Учитывать в КФО» и меню: «Перенести в правило…» (правила — `candidate_rule_ids` строки; фронт сам не сверяет
|
||||
счета с правилами), «Убрать из правила», «Вернуть к автоматике» (если `decision = ASSIGN`).
|
||||
- **Флажок агрегата** «Учитывать в КФО» — только показ: «Да» — все строки учитываются, «Частично» — часть исключена, «Нет» —
|
||||
все исключены. Сам признак ставится на строке (DOC-272613; ждёт п. 4).
|
||||
- **Нераспределённые строки** — после агрегатов, фон приглушён. Владелец — на своей стороне (дебетовая строка — в «Дебет»,
|
||||
кредитовая — в «Кредит»), на другой стороне — только ЮЛ контрагента. Строка баланса не показывается (DOC-272613 п. 4.3).
|
||||
Флажок «Учитывать в КФО», меню «Отнести к правилу…» (список — `candidate_rule_ids`), «Вернуть к автоматике» для
|
||||
`reason = UNASSIGNED`. Кнопки «Корректировать» нет (ждёт п. 2).
|
||||
- **«Итого»** — суммы сторон, отклонения и корректировок по видимым агрегатам, точным сложением строк; процент «Итого» не
|
||||
показываем (смысл не задан).
|
||||
- Подписи «Отнести/Перенести в правило…» показывают правила как пресеты: «Правило N: <статья 1> — <статья 2>».
|
||||
|
||||
### Панель
|
||||
|
||||
- «Отображение»: «Общий» / «По пресету»; при «По пресету» — выбор правила (подпись с номером — снимает одинаковые подписи
|
||||
правил 5 и 8 из дизайна, п. 12); в таблице только агрегаты этого правила и те нераспределённые строки, у которых это
|
||||
правило есть в `candidate_rule_ids` (их можно отнести к нему).
|
||||
- «Тип записи»: «Все» / «Пары счетов» (агрегаты) / «Нераспределенные записи».
|
||||
- Фильтры «ЮЛ» и «Счёт» действуют и на нераспределённые строки; «Строка баланса» и «Отклонение» — только на агрегаты, при
|
||||
заданном одном из них нераспределённые строки скрываются (у них нет статьи и отклонения).
|
||||
- Составная статья правила (`"1450/1550"`, `"1310/1350"`, правила 1 и 2) показывается как «1450 / 1550»; в фильтре
|
||||
«Строка баланса» это два кода; в окне корректировки подставляется первый код, аналитик может выбрать второй.
|
||||
- Единицы и знаки — тот же компонент, что в шахматке.
|
||||
- Фильтры в заголовках: ЮЛ (подстрока, обе стороны), Строка баланса (список), Счёт (начало кода), Отклонение %
|
||||
(«Все» / «≥ 5 %» / «< 5 %», по `exceeds_threshold`); «Сбросить фильтры» — когда что-то задано.
|
||||
- «Настройка таблицы» — `GenericTable/ColumnSettings` (видимость групп и колонок); «Экспорт» — файл сервера; «На весь экран» —
|
||||
как в шахматке.
|
||||
|
||||
### Окно «Корректировка операции»
|
||||
|
||||
По дизайну: шапка сторон (компания, статья правила), блоки «Исходные данные ОСВ» и «Распределение корректировки» для
|
||||
каждой стороны, итоги, комментарий, «Отменить» / «Сохранить корректировки».
|
||||
|
||||
- **Исходные данные ОСВ** — строки стороны агрегата. «×» у строки — «Убрать из правила» (`UNASSIGN`), «Добавить строку ОСВ» —
|
||||
выбор из нераспределённых строк, которые подходят под эту сторону: та же пара компаний (владелец и контрагент), сторона
|
||||
строки = сторона правила, правило агрегата есть в `candidate_rule_ids` (ответ 3(а)). Обе операции идут на сервер сразу
|
||||
(`POST …/allocations`), окно перечитывает агрегат.
|
||||
- **Распределение** — статьи стороны: строка баланса (код статьи) и сумма; «Добавить строку» — дочерняя статья. Без
|
||||
корректировки окно предлагает по стороне одну статью правила с суммой стороны (как в дизайне).
|
||||
- **Контроль** — суммы исходных строк сторон и суммы распределения сторон, разница и процент к меньшему (как в таблице;
|
||||
79,77 % из дизайна — ошибка дизайна, п. 7). Расхождение не запрещает сохранение (ждёт п. 8).
|
||||
- **Сохранить** — `PUT` с `status = APPLIED`, `expected_version_no` из ответа; ошибки сервера показываются в окне по коду
|
||||
(`COMMENT_REQUIRED` — у поля комментария, `INVALID_LINE_CODE` — у статьи, `CORRECTION_VERSION_CONFLICT` — «Корректировку уже
|
||||
изменили, таблица обновлена», окно перечитывает данные).
|
||||
- **Черновик окна в `localStorage`** (решение владельца 28.10.2026 вместо блокировки переходов): статьи распределения и
|
||||
комментарий сохраняются при каждой правке; ключ — пользователь + версия + агрегат (`rule_id`, компании), в записи — время
|
||||
и `version_no` корректировки, от которой начаты правки. Переход «Назад», закрытие вкладки, переход по ссылке правки не
|
||||
теряют. При открытии окна этого агрегата черновик подставляется с плашкой «Восстановлены несохранённые правки от ЧЧ:ММ» и
|
||||
кнопкой «Сбросить»; если `version_no` на сервере уже другой — плашка «Корректировку изменили после ваших правок»
|
||||
(аналитик решает: оставить или сбросить). Черновик удаляется после успешного сохранения и после «Отменить» с
|
||||
подтверждением «Есть несохранённые изменения. Закрыть без сохранения?». Действия со строками в черновик не входят (они уже
|
||||
на сервере). Доступ к хранилищу — в `try/catch`: недоступно (приватный режим) — работаем без черновика.
|
||||
|
||||
### Только чтение
|
||||
|
||||
`editable = false` — «Корректировать», флажки и меню решений неактивны; подсказка по `read_only_reason`:
|
||||
`VERSION_NOT_EDITABLE` — «Версия закрыта для изменений», `LOCK_REQUIRED` — «Возьмите консолидацию в работу»,
|
||||
`LOCKED_BY_OTHER` — «Консолидацию редактирует другой пользователь». Окно корректировки открывается на просмотр.
|
||||
|
||||
### Состояния
|
||||
|
||||
Загрузка — индикатор на месте таблицы; ошибка — уведомление с текстом сервера и «Повторить»; пусто — «Внутригрупповых
|
||||
остатков между компаниями периметра нет»; фильтры ничего не нашли — «Нет записей для выбранных фильтров» (текст дизайна).
|
||||
|
||||
## Что оставлено исполнителю
|
||||
|
||||
Разбиение на компоненты и хуки, имена файлов внутри `widgets/CorrectionTable/`, способ раскрытия (antd `expandable` или
|
||||
собственные строки), вид меню действий, точная раскладка окна в пределах дизайна, состав данных фейка.
|
||||
|
||||
## Decisions made without discussion
|
||||
|
||||
| Дата | Решение | Почему | Цена ошибки |
|
||||
|---|---|---|---|
|
||||
| 28.10.2026 | Контракт API пишем сами (docs #183), markdown + OpenAPI; корректировка в контракте — только на агрегат | API ещё нет; аналитика приоритетна | при ответе «можно на строку» (п. 2) — новый эндпоинт и кнопки на строках |
|
||||
| 28.10.2026 | Раскрытие агрегата — строки ОСВ под своей стороной, не пары из дизайна | DOC-272613 п. 3.4; пары нигде не хранятся | ответ по п. 3 «пары нужны» — доработка раскрытия и контракта |
|
||||
| 28.10.2026 | «Учитывать в КФО» ставится на строке; у агрегата — производное «Да / Частично / Нет» | DOC-272613 (EXCLUDE на `osv_entry`) | ответ по п. 4 «на агрегат» — поменять флажок агрегата на действие |
|
||||
| 28.10.2026 | Действия со строками в окне корректировки идут на сервер сразу, статьи и комментарий — по «Сохранить» | разнесение и корректировка — разные записи (`vgo_assignment` / `correction`); аналитик видит новые суммы до ввода корректировки | отмена окна не откатывает перенос строк — аналитику нужно вернуть строку вручную |
|
||||
| 28.10.2026 | Сохранение сразу применяет (`APPLIED`), черновик не показываем | в дизайне одна кнопка | ответ по п. 9 «нужен черновик» — вторая кнопка |
|
||||
| 28.10.2026 | «Отменить корректировку» — в меню агрегата, с комментарием | `REVOKED` в аналитике есть, в дизайне нет места | ответ по п. 9 — перенести кнопку |
|
||||
| 28.10.2026 | Процент в окне — к меньшему, как в таблице | аналитика; в дизайне две формулы | — |
|
||||
| 28.10.2026 | Без корректировки окно предлагает суммы сторон целиком | так в дизайне; в аналитике подсказка не описана | ответ по п. 8 — поменять подсказку на min |
|
||||
| 28.10.2026 | Фильтр «Отклонение» — по `exceeds_threshold` (≥ 5 % / < 5 %), а не диапазон чисел | порог — главный вопрос аналитика; диапазон в дизайне не описан | доработка фильтра |
|
||||
| 28.10.2026 | «Итого» без процента | смысл процента по итогам не задан | добавить колонку |
|
||||
| 28.10.2026 | Фейк контракта под флагом `REACT_APP_CORRECTIONS_MOCK`, данные из дизайна | фронт не ждёт бэкенд; тот же код ходит в настоящий API | фейк расходится с бэкендом — ловится при подключении API и ревью AURORA-1540 |
|
||||
| 28.10.2026 | Только `statement_type = balance`, переключателя ББ/ОФР нет | в дизайне его нет; ОФР ждёт AURORA-1396 | добавить переключатель |
|
||||
| 28.10.2026 | Ключ черновика — пользователь + версия + агрегат; черновик без срока жизни, удаляется сохранением или «Отменить» | на общем компьютере у разных пользователей разные черновики | старые черновики копятся в `localStorage` — объём мал |
|
||||
| 28.10.2026 | План — только `web/`, бэкенду помогаем на ревью 1540; последняя задача — подключение к API и снятие флага | слова владельца «поможем ребятам на ревью» | если 1540 не успеет к 02.11, экран сдаётся на фейке |
|
||||
| 28.10.2026 | В контракт добавлен `candidate_rule_ids` у строки агрегата | иначе фронту пришлось бы сверять счета с правилами — это разнесение, анти-цель | правка контракта до начала 1540 — дёшево |
|
||||
| 28.10.2026 | `expected_version_no = null`, когда действующей корректировки нет (и после отзыва) | иначе после отзыва фронту неоткуда взять номер | — |
|
||||
| 28.10.2026 | Составная статья правил 1 и 2 — в окне первый код, можно выбрать второй | `line_code` — один код; особый расчёт правил 1 и 2 (DOC-274230) — на сервере | при ответе «нужно распределение по обеим» — аналитик добавляет вторую статью руками |
|
||||
| 28.10.2026 | «По пресету» показывает и подходящие нераспределённые строки; «Строка баланса» и «Отклонение» скрывают нераспределённые | пресет — рабочее место по правилу, строки для отнесения нужны рядом | поменять функцию фильтров |
|
||||
61
openspec/changes/corrections-table-ui/proposal.md
Normal file
61
openspec/changes/corrections-table-ui/proposal.md
Normal file
@ -0,0 +1,61 @@
|
||||
## Why
|
||||
|
||||
AURORA-1541: вкладка «Таблица корректировки» страницы отчёта версии — заглушка «Будет в следующих срезах». Аналитику нужен
|
||||
экран, где видно расхождения ВГО по правилам и парам компаний, строки ОСВ, из которых они сложились, нераспределённые
|
||||
строки, и где вносится корректировка агрегата. Срок задачи — 02.11.2026, к 03.11 начинается тестирование корректировок
|
||||
(AURORA-1542).
|
||||
|
||||
Основа — аналитика Лысенко (DOC-272613 «Корректировка данных агрегатом», ответы на вопросы 1–7 от 27.10.2026 в AURORA-1395,
|
||||
DOC-274230 «Правила пар счетов») и дизайн от 23.10.2026 (вложение к DOC-272613). Где дизайн расходится с аналитикой,
|
||||
действует аналитика (решение владельца 28.10.2026); вопросы по расхождениям — комментарий `[design-23-10-check]` в
|
||||
AURORA-1395 и в AURORA-1396.
|
||||
|
||||
## What Changes
|
||||
|
||||
Срез 5 (`09-delivery-plan.md`, «ВГО: автоматическое сопоставление, шахматка, корректировки»). Репозиторий — arm-core,
|
||||
только `web/`. Бэкенд — AURORA-1540 (Цыганков) по контракту `../docs/dev/api-contract-corrections.md` +
|
||||
`api-contract-corrections.openapi.yaml` (docs #183); пока API нет, экран работает на встроенном фейке контракта под флагом
|
||||
`REACT_APP_CORRECTIONS_MOCK`.
|
||||
|
||||
- Вкладка «Таблица корректировки» (`…/versions/{id}/correction`) становится доступной.
|
||||
- Таблица агрегатов «правило × компания 1 × компания 2»: блоки Дебет / Кредит / Контроль / Корректировка, раскрытие до строк
|
||||
ОСВ под своей стороной, нераспределённые строки после агрегатов, строка «Итого» по видимым строкам.
|
||||
- Панель: «Отображение» (Общий / По пресету + выбор правила), «Тип записи», единицы и знаки, «Сбросить фильтры»,
|
||||
«Настройка таблицы», «Экспорт», «На весь экран»; фильтры в заголовках колонок.
|
||||
- Окно «Корректировка операции» агрегата: исходные строки ОСВ сторон (убрать, добавить подходящую нераспределённую),
|
||||
распределение по статьям каждой стороны, контроль распределения, комментарий, «Сохранить корректировки».
|
||||
- Решения по строке: «Учитывать в КФО» (флажок строки), «Отнести к правилу» / «Перенести в правило», «Убрать из правила»,
|
||||
«Вернуть к автоматике»; «Отменить корректировку» агрегата с комментарием.
|
||||
- Режим только чтения по `editable` / `read_only_reason` ответа.
|
||||
- Новая спека `corrections-table-ui`; дельта `intercompany-matrix-ui` (вкладка «Таблица корректировки» доступна).
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Бэкенд, DBML (`correction` как есть в v5.23; `vgo_assignment` — новая версия DBML в рамках AURORA-1540).
|
||||
- ОФР: в дизайне его нет, вопрос в AURORA-1396; экран запрашивает только `statement_type = balance`.
|
||||
- Импорт xlsx (вопрос по ТЗ 6.8 в `[design-23-10-check]`).
|
||||
- Корректировка строки ОСВ и нераспределённой строки — по аналитике корректируется только агрегат (ждёт п. 2).
|
||||
- Переход из ячейки шахматки в таблицу с фокусом на паре — AURORA-1653.
|
||||
- Учёт корректировок в шахматке — AURORA-1643.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `corrections-table-ui`: экран «Таблица корректировки» версии консолидации.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `intercompany-matrix-ui`: MODIFIED «Вкладки страницы отчёта по версии» — «Таблица корректировки» доступна.
|
||||
|
||||
## Impact
|
||||
|
||||
- `web/src/widgets/ConsolidatedOsv/OsvTabs.tsx` — вкладка `correction` без `disabled`.
|
||||
- `web/src/layouts/ConsolidationReportPage.tsx` — содержимое вкладки `correction`.
|
||||
- Новое: `web/src/widgets/CorrectionTable/` (таблица, панель, окно корректировки, чистые функции + тесты),
|
||||
`web/src/services/api/corrections.ts`, типы контракта в `web/src/types/api.ts` (или `types/corrections.ts`), фейк контракта.
|
||||
- `web/src/conf/config.ts` — флаг `REACT_APP_CORRECTIONS_MOCK`.
|
||||
- Таблицы DBML v5.23: `correction`, `elimination_rule`, `osv_entry` — только читаются через API; новых полей фронт не вводит.
|
||||
- Правила: `05-domain-rules.md` §8 (корректировки) в нынешнем виде описывает только запись корректировки; разнесение строк и
|
||||
`vgo_assignment` в §8 нет — ASSUMPTION: до обновления §8 источник — DOC-272613 и ответы 1–7 (обновление §8 и DBML —
|
||||
в рамках AURORA-1540 / AURORA-1751).
|
||||
@ -0,0 +1,184 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Загрузка таблицы корректировок
|
||||
Вкладка `correction` страницы отчёта версии SHALL загружать таблицу одним запросом
|
||||
`GET /consolidations/versions/{id}/corrections?statement_type=balance` (контракт `../docs/dev/api-contract-corrections.md`)
|
||||
и показывать её целиком: строки агрегатов (`aggregates[]`) в порядке ответа, затем нераспределённые строки
|
||||
(`unallocated[]`), внизу строку «Итого». Пока идёт загрузка, на месте таблицы SHALL быть индикатор; ошибка API SHALL
|
||||
показываться уведомлением с текстом сервера и кнопкой «Повторить». Пустой ответ SHALL показывать текст «Внутригрупповых
|
||||
остатков между компаниями периметра нет». Разнесение строк, отклонения, порог 5 % и статусы агрегатов фронт SHALL брать из
|
||||
ответа и не пересчитывать. При `REACT_APP_CORRECTIONS_MOCK=true` те же запросы SHALL обслуживаться фейком контракта в памяти.
|
||||
|
||||
#### Scenario: Открытие вкладки
|
||||
- **WHEN** аналитик открывает `…/versions/{id}/correction`
|
||||
- **THEN** выполняется один запрос таблицы, показываются агрегаты, после них нераспределённые строки и строка «Итого»
|
||||
|
||||
#### Scenario: Ошибка загрузки
|
||||
- **WHEN** сервер вернул 500
|
||||
- **THEN** показано уведомление с текстом ошибки и кнопка «Повторить», повторный запрос выполняется по нажатию
|
||||
|
||||
### Requirement: Колонки и строка агрегата
|
||||
Таблица SHALL иметь колонки «Учитывать в КФО»; группу «Дебет» — «ЮЛ», «Строка баланса», «Счёт», «Сумма»; группу «Кредит» —
|
||||
те же четыре; группу «Контроль» — «Отклонение, %», «Отклонение, сумма»; группу «Корректировка» — «Строка баланса», «Сумма»
|
||||
(Дт), «Строка баланса», «Сумма» (Кт), «Комментарий»; колонку действий. Строка агрегата SHALL показывать: компании
|
||||
`company_1` / `company_2`, статьи `side_1.article_line` / `side_2.article_line`, счета `accounts` через запятую, суммы сторон,
|
||||
`deviation_percent` (пусто — «—») и `deviation_amount`; при `exceeds_threshold = true` процент и сумма отклонения SHALL быть
|
||||
красными. Блок «Корректировка» SHALL показывать статьи и суммы `correction.debit` / `correction.credit` (по строке на статью)
|
||||
и `correction.comment`; без корректировки — «—». Корректировка в статусе `DRAFT` SHALL помечаться «черновик». Агрегат с
|
||||
`composition_changed = true` SHALL подсвечиваться и иметь значок с подсказкой «Состав изменился после корректировки».
|
||||
|
||||
#### Scenario: Расхождение выше порога
|
||||
- **WHEN** у агрегата «ЭПТ — ИЛС» `amount 1000000.00 / 202320.00`, `deviation_percent = "394.27"`, `exceeds_threshold = true`,
|
||||
выбраны «тыс. руб.» и 2 знака
|
||||
- **THEN** в строке видно `1 000,00`, `202,32`, красные `394,27%` и `797,68`
|
||||
|
||||
#### Scenario: Корректировка по двум статьям стороны
|
||||
- **WHEN** у корректировки агрегата `credit = [{1520, 500000.00}, {1550, 500000.00}]`
|
||||
- **THEN** в ячейках «Строка баланса» и «Сумма» стороны Кт видно две строки: `1520` / `500,00` и `1550` / `500,00`
|
||||
|
||||
### Requirement: Раскрытие агрегата до строк ОСВ
|
||||
Строка агрегата SHALL раскрываться стрелкой слева. Под агрегатом SHALL показываться его строки: сначала `side_1.entries`,
|
||||
затем `side_2.entries`; строка стороны 1 заполняет в блоке «Дебет» «Счёт» и «Сумма», строки стороны 2 — то же в блоке
|
||||
«Кредит»; остальные ячейки пустые. У каждой строки SHALL быть флажок «Учитывать в КФО» (`excluded = false` — отмечен) и меню
|
||||
действий: «Перенести в правило…» (правила из `candidate_rule_ids` строки; пустой список — пункт неактивен), «Убрать из
|
||||
правила», «Вернуть к автоматике» (только при `decision = ASSIGN`). Строка с
|
||||
`excluded = true` SHALL показываться приглушённо.
|
||||
|
||||
#### Scenario: Агрегат из четырёх строк с каждой стороны
|
||||
- **WHEN** аналитик раскрывает агрегат «ООО "БЕКОВСКИЙ САХАРНЫЙ ЗАВОД" — БЕКОВСКИЙ САХАРНЫЙ КОМБИНАТ ООО» правила 6
|
||||
- **THEN** под ним видны строки 62.01, 60.02, 62.03, 76.01 в блоке «Дебет» и строки 76.07, 60.01, 60.03, 62.02 в блоке
|
||||
«Кредит», у каждой — флажок и меню
|
||||
|
||||
### Requirement: Нераспределённые строки
|
||||
После агрегатов SHALL показываться нераспределённые строки (`unallocated[]`) на приглушённом фоне: владелец (`owner`) — в
|
||||
блоке своей стороны (`side = D` — «Дебет», `K` — «Кредит») со счётом и суммой; в блоке другой стороны — только ЮЛ
|
||||
`counterparty`; «Строка баланса» обеих сторон, «Контроль» и «Корректировка» — «—». У строки SHALL быть флажок «Учитывать в КФО»
|
||||
и меню «Отнести к правилу…» (правила из `candidate_rule_ids`) и «Вернуть к автоматике» (только при `reason = UNASSIGNED`).
|
||||
Кнопки «Корректировать» у нераспределённой строки SHALL NOT быть.
|
||||
|
||||
#### Scenario: Кредитовая строка без пары
|
||||
- **WHEN** в `unallocated` строка владельца «ООО "БСК"» по 76.05 `side = K` на «ПМП ООО» на 142 878,00
|
||||
- **THEN** «ООО "БСК"», `76.05` и `142 878,00` — в блоке «Кредит», «ПМП ООО» — в «ЮЛ» блока «Дебет», меню предлагает правила из
|
||||
`candidate_rule_ids`
|
||||
|
||||
### Requirement: Флажок «Учитывать в КФО»
|
||||
Флажок строки ОСВ (в раскрытии и у нераспределённой строки) SHALL отправлять `POST …/corrections/allocations` с
|
||||
`action = EXCLUDE` (снят) или `INCLUDE` (поставлен) и заменять таблицу ответом. Флажок строки агрегата SHALL быть только
|
||||
показом: «Да» — все строки агрегата учитываются, «Частично» — часть исключена, «Нет» — все исключены.
|
||||
|
||||
#### Scenario: Исключить строку из КФО
|
||||
- **WHEN** в раскрытом агрегате аналитик снимает флажок у строки 62.03
|
||||
- **THEN** уходит `{action: "EXCLUDE", entry_ids: [...]}`, таблица обновляется ответом, у агрегата флажок «Частично»
|
||||
|
||||
### Requirement: Отнести, перенести и убрать строку
|
||||
«Отнести к правилу…» и «Перенести в правило…» SHALL открывать выбор правила с подписями «Правило N: <статья 1> — <статья 2>»
|
||||
и отправлять `action = ASSIGN` с `rule_id`; «Убрать из правила» — `action = UNASSIGN`; «Вернуть к автоматике» —
|
||||
`action = RESET`. Ответ (вся таблица) SHALL заменять показанную таблицу; ошибка 422 `RULE_NOT_APPLICABLE` SHALL показываться
|
||||
уведомлением с текстом сервера.
|
||||
|
||||
#### Scenario: Перенос строки в другое правило
|
||||
- **WHEN** аналитик выбирает у строки «Перенести в правило…» и «Правило 7: 1230 — 1410»
|
||||
- **THEN** уходит `{action: "ASSIGN", rule_id: <правило 7>, entry_ids: [...]}`, строка видна в агрегате правила 7
|
||||
|
||||
### Requirement: Окно «Корректировка операции»
|
||||
Кнопка «Корректировать» строки агрегата SHALL открывать окно «Корректировка операции» с двумя сторонами: компания и статья
|
||||
правила стороны; блок «Исходные данные ОСВ» (счёт, строка баланса, сумма строк стороны; «×» у строки — `UNASSIGN`;
|
||||
«Добавить строку ОСВ» — выбор из нераспределённых строк той же пары компаний, той же стороны, у которых правило агрегата есть
|
||||
в `candidate_rule_ids`, — `ASSIGN`); блок «Распределение корректировки» (статьи: строка баланса и сумма; «Добавить строку» —
|
||||
ещё статья стороны; «×» — удалить статью). Действия с исходными строками SHALL уходить на сервер сразу и перечитывать агрегат.
|
||||
Без корректировки окно SHALL предлагать по каждой стороне одну статью правила с суммой стороны; у составной статьи
|
||||
(«1450/1550») — первый код, второй доступен для выбора. Под блоками SHALL быть итоги
|
||||
сторон и разница с процентом к меньшему (красным, если процент ≥ 5 или одна сторона пуста), поле «Комментарий к
|
||||
корректировке», кнопки «Отменить» и «Сохранить корректировки».
|
||||
|
||||
#### Scenario: Окно агрегата без корректировки
|
||||
- **WHEN** аналитик нажимает «Корректировать» у агрегата «Пензенский Мир Продуктов — Регион-Сахар» правила 3 (29 742 550,00 /
|
||||
29 242 550,00)
|
||||
- **THEN** в распределении стороны Дт — статья `1170` с суммой `29 742 550,00`, стороны Кт — `1410` с `29 242 550,00`, разница
|
||||
`500 000,00 (1,71%)`
|
||||
|
||||
#### Scenario: Добавить строку ОСВ
|
||||
- **WHEN** в окне агрегата пары «Пензенский Мир Продуктов — Бековский сахарный комбинат» правила 6 аналитик нажимает
|
||||
«Добавить строку ОСВ» на стороне Кт
|
||||
- **THEN** список содержит только нераспределённые кредитовые строки «Бековский сахарный комбинат ООО» на «Пензенский Мир
|
||||
Продуктов», подходящие под правило 6; выбор строки отправляет `ASSIGN` и обновляет суммы стороны
|
||||
|
||||
### Requirement: Сохранение корректировки
|
||||
«Сохранить корректировки» SHALL отправлять `PUT …/corrections/aggregates/{rule_id}/{company_1_id}/{company_2_id}` со статьями
|
||||
обеих сторон (первая статья стороны — основная), комментарием, `status = APPLIED` и `expected_version_no` из ответа (`null` —
|
||||
действующей корректировки нет, в том числе после отзыва) и после ответа закрывать окно и обновлять агрегат в таблице. Ошибки SHALL показываться в окне: `COMMENT_REQUIRED` — у
|
||||
поля комментария, `INVALID_LINE_CODE` — у статьи `detail.line_code`, `CORRECTION_VERSION_CONFLICT` — сообщением «Корректировку
|
||||
уже изменили, данные обновлены» с перечитыванием таблицы, остальные — текстом сервера. Закрытие окна с несохранёнными
|
||||
статьями или комментарием SHALL спрашивать «Есть несохранённые изменения. Закрыть без сохранения?».
|
||||
|
||||
#### Scenario: Сохранить без комментария
|
||||
- **WHEN** аналитик сохраняет корректировку с пустым комментарием и сервер отвечает 422 `COMMENT_REQUIRED`
|
||||
- **THEN** окно остаётся открытым, у поля комментария — текст ошибки
|
||||
|
||||
#### Scenario: Закрыть с несохранённым
|
||||
- **WHEN** аналитик изменил сумму статьи и нажал «Отменить»
|
||||
- **THEN** появляется вопрос «Есть несохранённые изменения. Закрыть без сохранения?»; «Остаться» оставляет окно с правками
|
||||
|
||||
### Requirement: Черновик окна корректировки
|
||||
Статьи распределения и комментарий открытого окна SHALL сохраняться в `localStorage` при каждой правке под ключом
|
||||
«пользователь + версия + агрегат» вместе со временем и `version_no` корректировки, от которой начаты правки. При открытии окна
|
||||
агрегата с черновиком окно SHALL подставлять черновик и показывать плашку «Восстановлены несохранённые правки от ЧЧ:ММ» с
|
||||
кнопкой «Сбросить»; если `version_no` действующей корректировки отличается от сохранённого в черновике — плашку
|
||||
«Корректировку изменили после ваших правок». Черновик SHALL удаляться после успешного сохранения, после «Сбросить» и после
|
||||
«Отменить» с подтверждением. Недоступное хранилище SHALL NOT ломать окно — оно работает без черновика.
|
||||
|
||||
#### Scenario: Ушёл со страницы и вернулся
|
||||
- **WHEN** аналитик изменил сумму статьи в окне агрегата, нажал «Назад» в браузере, потом снова открыл вкладку и окно этого
|
||||
агрегата
|
||||
- **THEN** в окне его сумма и плашка «Восстановлены несохранённые правки от …»
|
||||
|
||||
#### Scenario: Корректировку изменили, пока аналитик отсутствовал
|
||||
- **WHEN** в черновике `version_no = 2`, а в ответе таблицы у корректировки агрегата `version_no = 3`
|
||||
- **THEN** окно подставляет черновик и показывает плашку «Корректировку изменили после ваших правок» с кнопкой «Сбросить»
|
||||
|
||||
### Requirement: Отмена корректировки
|
||||
У агрегата с корректировкой меню действий SHALL содержать «Отменить корректировку»: окно с обязательным комментарием,
|
||||
`POST …/revoke`, после ответа агрегат обновляется и блок «Корректировка» показывает «—».
|
||||
|
||||
#### Scenario: Отмена корректировки
|
||||
- **WHEN** аналитик выбирает «Отменить корректировку» у агрегата «Сатурн — Архол» и вводит комментарий
|
||||
- **THEN** уходит `POST …/revoke {comment}`, у агрегата в блоке «Корректировка» — «—»
|
||||
|
||||
### Requirement: Панель и фильтры
|
||||
Над таблицей SHALL быть: «Отображение» — «Общий» / «По пресету»; при «По пресету» — поле «Правило» с правилами `rules[]`
|
||||
(подпись «Правило N: <статья 1> — <статья 2>», составная статья — «1450 / 1550») и в таблице только агрегаты выбранного
|
||||
правила и нераспределённые строки, у которых оно есть в `candidate_rule_ids`; «Тип записи» — «Все», «Пары
|
||||
счетов» (только агрегаты), «Нераспределенные записи» (только нераспределённые); единицы и знаки — как в шахматке; «Сбросить
|
||||
фильтры» — когда задан любой фильтр; справа — «Настройка таблицы», «Экспорт», «На весь экран». В заголовках SHALL быть
|
||||
фильтры: «ЮЛ» (подстрока имени, по обеим сторонам), «Строка баланса» (выбор кода), «Счёт» (начало кода, по счетам строки),
|
||||
«Отклонение, %» («Все» / «≥ 5 %» / «< 5 %» по `exceeds_threshold`). Фильтры «ЮЛ» и «Счёт» SHALL действовать и на
|
||||
нераспределённые строки; при заданном фильтре «Строка баланса» или «Отклонение, %» нераспределённые строки SHALL скрываться.
|
||||
Составная статья правила (коды через «/») в фильтре «Строка баланса» SHALL давать отдельные коды. Фильтры ничего не нашли —
|
||||
текст «Нет записей для выбранных фильтров». Строка «Итого» SHALL суммировать видимые агрегаты точным сложением: суммы сторон, отклонение, суммы
|
||||
корректировок Дт и Кт; процент в «Итого» — «—».
|
||||
|
||||
#### Scenario: Пресет правила 3
|
||||
- **WHEN** выбраны «По пресету» и «Правило 3: 1170 — 1410»
|
||||
- **THEN** в таблице только агрегаты правила 3, «Итого» — по ним
|
||||
|
||||
#### Scenario: Только нераспределённые
|
||||
- **WHEN** «Тип записи» — «Нераспределенные записи»
|
||||
- **THEN** агрегатов и «Итого» по агрегатам нет, видны только нераспределённые строки
|
||||
|
||||
### Requirement: Экспорт
|
||||
«Экспорт» SHALL скачивать файл `GET …/corrections/export?statement_type=balance` с именем из ответа сервера; ошибка —
|
||||
уведомлением с текстом сервера.
|
||||
|
||||
#### Scenario: Выгрузка
|
||||
- **WHEN** аналитик нажимает «Экспорт»
|
||||
- **THEN** браузер сохраняет xlsx, кнопка на время запроса показывает загрузку
|
||||
|
||||
### Requirement: Только чтение
|
||||
При `editable = false` кнопки «Корректировать» SHALL открывать окно только на просмотр, флажки «Учитывать в КФО» и пункты меню
|
||||
решений и отмены SHALL быть неактивны с подсказкой по `read_only_reason`: `VERSION_NOT_EDITABLE` — «Версия закрыта для
|
||||
изменений», `LOCK_REQUIRED` — «Возьмите консолидацию в работу», `LOCKED_BY_OTHER` — «Консолидацию редактирует другой
|
||||
пользователь». Ответы 409 правок версии SHALL показываться уведомлением с текстом сервера и перечитыванием таблицы.
|
||||
|
||||
#### Scenario: Верифицированная версия
|
||||
- **WHEN** сервер вернул `editable = false`, `read_only_reason = "VERSION_NOT_EDITABLE"`
|
||||
- **THEN** флажки неактивны, в окне корректировки нет «Сохранить корректировки», подсказка — «Версия закрыта для изменений»
|
||||
@ -0,0 +1,34 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Вкладки страницы отчёта по версии
|
||||
Страница `/groups/:group_id/versions/:version_id/:tab` SHALL показывать шапку версии (ГК, период, статус отчёта) один раз
|
||||
и под ней ряд вкладок шагов консолидации и содержимое активной вкладки. Активная вкладка определяется сегментом `:tab`:
|
||||
`osv` — «ОСВ» (сводная ОСВ), `chess` — «Шахматка», `correction` — «Таблица корректировки» (спека `corrections-table-ui`).
|
||||
Выбор вкладки SHALL менять последний сегмент адреса на ключ вкладки
|
||||
(навигация, не локальное состояние) заменой текущей записи истории браузера, без новой записи: кнопка «Назад» в шапке и
|
||||
кнопка «Назад» браузера ведут туда, откуда открыт отчёт, а не по переключениям вкладок (AURORA-1851). Активная вкладка
|
||||
подсвечена зелёным и выделена жирным. Неизвестный ключ вкладки SHALL
|
||||
заменяться на `osv` без новой записи в истории браузера. Вкладки «Гудвилл», «КФО», «КФО Общий»,
|
||||
«Подтверждение КФО клиента» SHALL быть недоступны с подсказкой «Будет в следующих срезах». При смене `version_id` всё
|
||||
состояние страницы (карточка версии, данные, фильтры) SHALL создаваться заново.
|
||||
|
||||
#### Scenario: Переход на шахматку
|
||||
- **WHEN** открыта сводная ОСВ версии по адресу `…/versions/{id}/osv` и нажата вкладка «Шахматка»
|
||||
- **THEN** адрес становится `…/versions/{id}/chess`, шапка версии остаётся, под вкладками показана шахматка
|
||||
|
||||
#### Scenario: Переход на таблицу корректировки
|
||||
- **WHEN** открыта шахматка версии по адресу `…/versions/{id}/chess` и нажата вкладка «Таблица корректировки»
|
||||
- **THEN** адрес становится `…/versions/{id}/correction`, шапка версии остаётся, под вкладками показана таблица корректировок
|
||||
|
||||
#### Scenario: Прежний адрес сводной ОСВ
|
||||
- **WHEN** открыт адрес `…/versions/{id}/osv`
|
||||
- **THEN** показана сводная ОСВ, вкладка «ОСВ» активна
|
||||
|
||||
#### Scenario: Неизвестная вкладка
|
||||
- **WHEN** открыт адрес `…/versions/{id}/abc`
|
||||
- **THEN** адрес заменяется на `…/versions/{id}/osv`, показана сводная ОСВ; кнопка «Назад» браузера не возвращает на `…/abc`
|
||||
|
||||
#### Scenario: Назад после переключения вкладок
|
||||
- **WHEN** аналитик открыл отчёт версии кнопкой «К отчётности» в списке консолидаций, переключился «Шахматка» → «ОСВ» →
|
||||
«Шахматка» и нажал «Назад» в шапке
|
||||
- **THEN** одним нажатием открыт список консолидаций ГК
|
||||
Loading…
x
Reference in New Issue
Block a user