openspec archive: corrections-table-ui
Закрыт PR #215 (AURORA-1541, issue #206) — таблица корректировки подключена к реальному API.
This commit is contained in:
parent
49b18b8484
commit
967fa01fb6
193
openspec/specs/corrections-table-ui/spec.md
Normal file
193
openspec/specs/corrections-table-ui/spec.md
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
# corrections-table-ui Specification
|
||||||
|
|
||||||
|
## Purpose
|
||||||
|
TBD - created by archiving change corrections-table-ui. Update Purpose after archive.
|
||||||
|
|
||||||
|
## 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 брать из
|
||||||
|
ответа и не пересчитывать.
|
||||||
|
|
||||||
|
#### 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 помечаться «черновик». Флажок
|
||||||
|
«Учитывать в КФО» агрегата SHALL быть отмечен и неактивен всегда: агрегат учитывается в КФО целиком, лишнюю строку из него
|
||||||
|
убирают из правила (ответ Лысенко 29.10, п. 4). Агрегат с
|
||||||
|
`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 NOT быть — она учитывается вместе с
|
||||||
|
агрегатом. У каждой строки SHALL быть меню действий: «Перенести в правило…» (правила из `candidate_rule_ids` строки; пустой
|
||||||
|
список — пункт неактивен), «Убрать из правила» (строка уходит в нераспределённые), «Вернуть к автоматике» (только при
|
||||||
|
`decision = ASSIGN`).
|
||||||
|
|
||||||
|
#### 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` — «Кредит») со строкой баланса `line_code` (нет — «—»), счётом и суммой; в
|
||||||
|
блоке другой стороны — только ЮЛ `counterparty`; «Строка баланса» другой стороны, «Контроль» и «Корректировка» — «—».
|
||||||
|
Строка с `excluded = true` SHALL показываться приглушённо. У строки SHALL быть флажок «Учитывать в КФО»
|
||||||
|
и меню «Отнести к правилу…» (правила из `candidate_rule_ids`) и «Вернуть к автоматике» (только при `reason = UNASSIGNED`).
|
||||||
|
Кнопки «Корректировать» у нераспределённой строки SHALL NOT быть.
|
||||||
|
|
||||||
|
#### Scenario: Кредитовая строка без пары
|
||||||
|
- **WHEN** в `unallocated` строка владельца «ООО "БСК"» по 76.05 `side = K` на «ПМП ООО» на 142 878,00
|
||||||
|
- **THEN** «ООО "БСК"», `1520`, `76.05` и `142 878,00` — в блоке «Кредит», «ПМП ООО» — в «ЮЛ» блока «Дебет», меню предлагает
|
||||||
|
правила из `candidate_rule_ids`
|
||||||
|
|
||||||
|
### Requirement: Флажок «Учитывать в КФО»
|
||||||
|
Флажок нераспределённой строки SHALL отправлять `PUT …/vgo-assignments/exclude` с `is_exclude = true` (снят) или `false`
|
||||||
|
(поставлен) и затем перечитывать таблицу целиком. Флажок агрегата SHALL быть отмечен и неактивен с подсказкой «Агрегат всегда
|
||||||
|
учитывается в КФО; лишнюю строку уберите из правила»; у строк агрегата флажка SHALL NOT быть (ответ Лысенко 29.10, п. 4).
|
||||||
|
|
||||||
|
#### Scenario: Исключить нераспределённую строку из КФО
|
||||||
|
- **WHEN** аналитик снимает флажок у нераспределённой строки «ЭПТ» по 76.09
|
||||||
|
- **THEN** уходит `{action: "EXCLUDE", entry_ids: [...], side: "D"}`, таблица обновляется ответом, строка приглушена
|
||||||
|
|
||||||
|
#### Scenario: Убрать строку из агрегата
|
||||||
|
- **WHEN** в окне корректировки агрегата «ООО "БЕКОВСКИЙ САХАРНЫЙ ЗАВОД" — БЕКОВСКИЙ САХАРНЫЙ КОМБИНАТ ООО» аналитик нажимает «×»
|
||||||
|
у строки 62.03
|
||||||
|
- **THEN** уходит `{action: "UNASSIGN"}`, сумма стороны Дт уменьшается на 350 000,00, строка 62.03 видна в нераспределённых
|
||||||
|
со строкой баланса `1230`
|
||||||
|
|
||||||
|
### 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}` со статьями
|
||||||
|
обеих сторон (первая статья стороны — основная), комментарием и `expected_version_no` из ответа (`null` — действующей
|
||||||
|
корректировки нет); сервер сразу применяет корректировку (`APPLIED`). После ответа окно SHALL закрываться, агрегат в таблице —
|
||||||
|
обновляться. Ошибки 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 быть: «Отображение» — «Общий» / «По пресету»; при «По пресету» — поле «Правило» с правилами `rules[]`
|
||||||
|
(подпись «Правило N: <статья 1> — <статья 2>», составная статья — «1450 / 1550») и в таблице только агрегаты выбранного
|
||||||
|
правила и нераспределённые строки, у которых оно есть в `candidate_rule_ids`; «Тип записи» — «Все», «Пары
|
||||||
|
счетов» (только агрегаты), «Нераспределенные записи» (только нераспределённые); единицы и знаки — как в шахматке; «Сбросить
|
||||||
|
фильтры» — когда задан любой фильтр; справа — «Настройка таблицы», «Экспорт», «На весь экран». В заголовках SHALL быть
|
||||||
|
фильтры: «ЮЛ» (подстрока имени, по обеим сторонам), «Строка баланса» (выбор кода), «Счёт» (начало кода, по счетам строки),
|
||||||
|
«Отклонение, %» («Все» / «> 5 %» / «≤ 5 %» по `exceeds_threshold`). Фильтры «ЮЛ», «Счёт» и «Строка баланса» SHALL
|
||||||
|
действовать и на нераспределённые строки («Строка баланса» — по `line_code`, строка без него скрывается, её коды есть в
|
||||||
|
выборе); при заданном фильтре «Отклонение, %» нераспределённые строки 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** флажки неактивны, в окне корректировки нет «Сохранить корректировки», подсказка — «Версия закрыта для изменений»
|
||||||
@ -8,11 +8,12 @@
|
|||||||
### Requirement: Вкладки страницы отчёта по версии
|
### Requirement: Вкладки страницы отчёта по версии
|
||||||
Страница `/groups/:group_id/versions/:version_id/:tab` SHALL показывать шапку версии (ГК, период, статус отчёта) один раз
|
Страница `/groups/:group_id/versions/:version_id/:tab` SHALL показывать шапку версии (ГК, период, статус отчёта) один раз
|
||||||
и под ней ряд вкладок шагов консолидации и содержимое активной вкладки. Активная вкладка определяется сегментом `:tab`:
|
и под ней ряд вкладок шагов консолидации и содержимое активной вкладки. Активная вкладка определяется сегментом `:tab`:
|
||||||
`osv` — «ОСВ» (сводная ОСВ), `chess` — «Шахматка». Выбор вкладки SHALL менять последний сегмент адреса на ключ вкладки
|
`osv` — «ОСВ» (сводная ОСВ), `chess` — «Шахматка», `correction` — «Таблица корректировки» (спека `corrections-table-ui`).
|
||||||
|
Выбор вкладки SHALL менять последний сегмент адреса на ключ вкладки
|
||||||
(навигация, не локальное состояние) заменой текущей записи истории браузера, без новой записи: кнопка «Назад» в шапке и
|
(навигация, не локальное состояние) заменой текущей записи истории браузера, без новой записи: кнопка «Назад» в шапке и
|
||||||
кнопка «Назад» браузера ведут туда, откуда открыт отчёт, а не по переключениям вкладок (AURORA-1851). Активная вкладка
|
кнопка «Назад» браузера ведут туда, откуда открыт отчёт, а не по переключениям вкладок (AURORA-1851). Активная вкладка
|
||||||
подсвечена зелёным и выделена жирным. Неизвестный ключ вкладки SHALL
|
подсвечена зелёным и выделена жирным. Неизвестный ключ вкладки SHALL
|
||||||
заменяться на `osv` без новой записи в истории браузера. Вкладки «Таблица корректировки», «Гудвилл», «КФО», «КФО Общий»,
|
заменяться на `osv` без новой записи в истории браузера. Вкладки «Гудвилл», «КФО», «КФО Общий»,
|
||||||
«Подтверждение КФО клиента» SHALL быть недоступны с подсказкой «Будет в следующих срезах». При смене `version_id` всё
|
«Подтверждение КФО клиента» SHALL быть недоступны с подсказкой «Будет в следующих срезах». При смене `version_id` всё
|
||||||
состояние страницы (карточка версии, данные, фильтры) SHALL создаваться заново.
|
состояние страницы (карточка версии, данные, фильтры) SHALL создаваться заново.
|
||||||
|
|
||||||
@ -20,6 +21,10 @@
|
|||||||
- **WHEN** открыта сводная ОСВ версии по адресу `…/versions/{id}/osv` и нажата вкладка «Шахматка»
|
- **WHEN** открыта сводная ОСВ версии по адресу `…/versions/{id}/osv` и нажата вкладка «Шахматка»
|
||||||
- **THEN** адрес становится `…/versions/{id}/chess`, шапка версии остаётся, под вкладками показана шахматка
|
- **THEN** адрес становится `…/versions/{id}/chess`, шапка версии остаётся, под вкладками показана шахматка
|
||||||
|
|
||||||
|
#### Scenario: Переход на таблицу корректировки
|
||||||
|
- **WHEN** открыта шахматка версии по адресу `…/versions/{id}/chess` и нажата вкладка «Таблица корректировки»
|
||||||
|
- **THEN** адрес становится `…/versions/{id}/correction`, шапка версии остаётся, под вкладками показана таблица корректировок
|
||||||
|
|
||||||
#### Scenario: Прежний адрес сводной ОСВ
|
#### Scenario: Прежний адрес сводной ОСВ
|
||||||
- **WHEN** открыт адрес `…/versions/{id}/osv`
|
- **WHEN** открыт адрес `…/versions/{id}/osv`
|
||||||
- **THEN** показана сводная ОСВ, вкладка «ОСВ» активна
|
- **THEN** показана сводная ОСВ, вкладка «ОСВ» активна
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user