20 KiB
intercompany-matrix-ui Specification
Purpose
Аналитик видит шахматку ВГО версии [31-01] (матрица Дт/Кт по компаниям с фильтрами компаний и счетов, единицами и полноэкранным режимом) и результирующую таблицу ВГО [31-01-01], выгружает обе в xlsx; суммы и итоги приходят с бэка, фронт их только форматирует.
Requirements
Requirement: Вкладки страницы отчёта по версии
Страница /groups/:group_id/versions/:version_id/:tab SHALL показывать шапку версии (ГК, период, статус отчёта) один раз
и под ней ряд вкладок шагов консолидации и содержимое активной вкладки. Активная вкладка определяется сегментом :tab:
osv — «ОСВ» (сводная ОСВ), chess — «Шахматка». Выбор вкладки SHALL менять последний сегмент адреса на ключ вкладки
(навигация, не локальное состояние), активная вкладка подсвечена зелёным и выделена жирным. Неизвестный ключ вкладки SHALL
заменяться на osv без новой записи в истории браузера. Вкладки «Таблица корректировки», «Гудвилл», «КФО», «КФО Общий»,
«Подтверждение КФО клиента» SHALL быть недоступны с подсказкой «Будет в следующих срезах». При смене version_id всё
состояние страницы (карточка версии, данные, фильтры) SHALL создаваться заново.
Scenario: Переход на шахматку
- WHEN открыта сводная ОСВ версии по адресу
…/versions/{id}/osvи нажата вкладка «Шахматка» - THEN адрес становится
…/versions/{id}/chess, шапка версии остаётся, под вкладками показана шахматка
Scenario: Прежний адрес сводной ОСВ
- WHEN открыт адрес
…/versions/{id}/osv - THEN показана сводная ОСВ, вкладка «ОСВ» активна
Scenario: Неизвестная вкладка
- WHEN открыт адрес
…/versions/{id}/abc - THEN адрес заменяется на
…/versions/{id}/osv, показана сводная ОСВ; кнопка «Назад» браузера не возвращает на…/abc
Requirement: Таблица шахматки ЮЛ × ЮЛ
Экран SHALL загружать матрицу при открытии вкладки (GET /consolidations/versions/{id}/intercompany-matrix/all) и показывать
таблицу: первая колонка «ДБ / КТ» (закреплена слева) — компании периметра в порядке ответа (companies[]), остальные колонки —
те же компании. В ячейке пары (строка A, колонка Б) SHALL быть три числа друг под другом: сумма amount_a, сумма amount_b
и расхождение variance_amount в скобках; расхождение выделяется красным, если exceeds_threshold = true или
one_sided = true (пара без встречной стороны; правило подсветки — как в API и xlsx, AURORA-1651). Если у пары есть
строки ОСВ без сопоставленного счёта (skipped_osv_entry_count > 0), рядом с первым числом SHALL показываться значок
предупреждения с подсказкой «Строк ОСВ без сопоставленного счёта: N; в суммы не вошли». Если ячейки пары в ответе нет
(в том числе на диагонали), SHALL показываться прочерк «—» на приглушённом фоне. Ниже таблицы закреплена строка «Итого»: до
появления итогов в API (AURORA-1756, AURORA-1757) она временно считается на клиенте точным сложением десятичных строк — сумма
amount_a по колонке видимых ячеек; итог, который не удалось сложить, показывается прочерком «—», а не нулём. Пока идёт
загрузка, таблица показывает индикатор загрузки; ошибка API показывается уведомлением с текстом сервера. Панель фильтров
показывает год и квартал версии неактивными полями «Год» и «Период» (например, 2024 и К1): версия задаётся адресом.
Scenario: Ячейка с расхождением выше порога
- WHEN для пары
(A, Б)сервер вернулexceeds_threshold = true - THEN третье число ячейки (расхождение) показано красным, первые два — обычным цветом
Scenario: Пара без встречной стороны
- WHEN для пары
(A, Б)сервер вернулamount_b = 0,one_sided = true,exceeds_threshold = false - THEN третье число ячейки (расхождение) показано красным
Scenario: Пары нет в ответе
- WHEN в
cells[]нет ячейки для пары компаний - THEN на их пересечении показан прочерк «—»
Scenario: Пропущенные строки ОСВ
- WHEN у ячейки
skipped_osv_entry_count = 2 - THEN у первого числа ячейки виден значок предупреждения, подсказка — «Строк ОСВ без сопоставленного счёта: 2; в суммы не вошли»
Requirement: Результирующая таблица ВГО
Под матрицей экран SHALL показывать результирующую таблицу ВГО, загруженную при открытии вкладки
(GET /consolidations/versions/{id}/intercompany-matrix/result-table): первая колонка «Статья» — статьи ответа (articles[],
name) в порядке ответа, далее колонки компаний (companies[]) с суммой статьи по компании (amounts[] по company_id) и
колонка «Итого» со значением group_total из ответа; пустая сумма — прочерк «—». Ниже таблицы закреплена строка «Итого»: до
появления итогов в API (AURORA-1756, AURORA-1757) она временно считается на клиенте точным сложением сумм всех статей по
колонке (итог, который не удалось сложить, — «—»). У таблицы свои выбор единиц и знаков (по правилам требования «Единицы и знаки», независимо от
матрицы), кнопка «Экспорт» и кнопка «На весь экран». Пока идёт загрузка, таблица показывает индикатор; ошибка API (в том числе
422 RESULT_ACCOUNTS_MISSING) показывается уведомлением с текстом сервера.
Scenario: Колонка «Итого» из ответа
- WHEN сервер вернул статью «Дебиторская задолженность» с
group_total = "1296510.00", выбраны «тыс. руб.» и 2 знака - THEN в колонке «Итого» этой статьи показано
1 296,51
Scenario: Нет обязательного счёта
- WHEN сервер ответил 422
RESULT_ACCOUNTS_MISSING - THEN показано уведомление с текстом сервера, матрица шахматки при этом показывается как обычно
Requirement: Единицы и знаки
Экран SHALL позволять выбрать единицы суммы — «руб.», «тыс. руб.» (по умолчанию), «млн. руб.», «млрд руб.» — и число знаков после запятой 0–3 (по умолчанию 2). Выбор применяется на клиенте к уже загруженным значениям (повторного запроса не делает): запятая сдвигается в десятичной строке на 3 / 6 / 9 разрядов, значение округляется до выбранного числа знаков (половина — от нуля) без перевода в число с плавающей точкой и показывается с разделителем разрядов и десятичной запятой. Значение, округлённое до нуля, показывается без минуса. Пустое значение — пустая ячейка. Значение, которое не удаётся прочитать как число, SHALL показываться как пришло — при любых единицах.
Scenario: Смена единиц
- WHEN выбраны «млн. руб.» и 1 знак, а сервер вернул
amount_a = "2346459.05" - THEN в ячейке показано
2,3
Scenario: Точное округление
- WHEN выбраны «тыс. руб.» и 2 знака, а сервер вернул
"1005" - THEN показано
1,01(не1,00, как дало бы округление числа с плавающей точкой)
Scenario: Маленькая отрицательная сумма
- WHEN выбраны «тыс. руб.» и 2 знака, а сервер вернул
"-4.00" - THEN показано
0,00, а не-0,00
Requirement: Фильтр компаний
Выбор «Компании» (множественный, пустой выбор — «Все компании») SHALL ограничивать матрицу на клиенте: остаются строки и колонки выбранных компаний и ячейки, у которых обе компании выбраны. Запрос на сервер при этом не отправляется. Список вариантов — компании последнего загруженного ответа. Выпадающее окно выбора — дерево с поиском по названию, кнопками применения и сброса.
Scenario: Две компании из периметра
- WHEN выбраны две компании из пяти
- THEN матрица содержит две строки и две колонки, «Итого» считается по оставшимся ячейкам
Requirement: Фильтр счетов Дт и Кт и режимы расчёта
Экран SHALL загружать план счетов GET /directories/accounts один раз при открытии и строить из него два дерева по иерархии
parent_id: дебетовые счета (is_debit) и кредитовые (is_credit); подпись узла — «код - название», в том числе у выбранных
дочерних счетов в поле выбора. Выбор счетов Дт и Кт — множественный, пустой выбор — «Все счета».
Отметки в дереве SHALL считаться по полному плану счетов: родительский счёт отмечен тогда и только тогда, когда отмечены все его потомки в полном дереве. Поиск по дереву скрывает не совпавшие узлы, но не меняет этого правила: отметка единственного видимого при поиске субсчёта не отмечает его родителя, а снятие отметки с субсчёта снимает её и с родителя. Скрытые поиском отметки при отметке видимых узлов сохраняются.
Режим расчёта определяется выбором:
- ничего не выбрано ни в Дт, ни в Кт — SHALL выполняться
GET …/intercompany-matrix/all(режимall); - выбраны счета и в Дт, и в Кт — SHALL выполняться
POST …/intercompany-matrix/manualс{debit_account_ids, credit_account_ids}(режимmanual); - выбрана только одна сторона — запрос SHALL NOT отправляться, таблица матрицы SHALL быть пустой и вместо данных показывать текст «Для расчёта по счетам выберите счета и в Дт, и в Кт»; тот же текст SHALL показываться у фильтров Дт/Кт (не всплывающим уведомлением) и только в этом состоянии; кнопка «Экспорт» матрицы SHALL быть недоступна.
Каждое изменение выбора счетов, приводящее к режиму all или manual, перезапрашивает матрицу; на экране остаётся ответ на
последний запрос, индикатор загрузки снимается и при переходе в состояние «выбрана одна сторона». Кнопка «Сбросить фильтры»
появляется, когда выбрано что-либо в компаниях, Дт или Кт, и очищает все три выбора. Выбор единиц и знаков кнопкой не
сбрасывается. Ошибка загрузки плана счетов показывается уведомлением.
Scenario: Обе стороны выбраны
- WHEN выбран счёт 60.01 в Дт и счёт 62.01 в Кт
- THEN отправляется
POST …/intercompany-matrix/manualс идентификаторами этих счетов и таблица показывает ответ
Scenario: Выбрана одна сторона
- WHEN выбран счёт только в Дт
- THEN запрос матрицы не отправляется, таблица пуста и показывает «Для расчёта по счетам выберите счета и в Дт, и в Кт», тот же текст виден у фильтров, «Экспорт» матрицы недоступен, выбор Дт остаётся в фильтре
Scenario: Выбрана одна сторона во время загрузки
- WHEN выбраны Дт и Кт, запрос
manualещё выполняется, и пользователь очищает Кт - THEN индикатор загрузки снят, ответ прежнего запроса на экран не выводится, таблица в состоянии «выбрана одна сторона»
Scenario: Поиск и отметка субсчёта
- WHEN в дереве Дт введён поиск, видна ветка 60 с единственным субсчётом 60.02, и отмечен 60.02
- THEN выбранным остаётся только 60.02; после сброса поиска счёт 60 и его прочие субсчета не отмечены
Scenario: Снятие субсчёта отмеченного родителя
- WHEN отмечен счёт 60 (отмечены 60, 60.01, 60.02) и снята отметка с 60.01
- THEN выбранным остаётся 60.02, счёт 60 не отмечен
Scenario: Сброс
- WHEN выбраны компании и счета, нажато «Сбросить фильтры»
- THEN все три выбора пусты, матрица перезапрошена в режиме
all, кнопка исчезла
Requirement: Экспорт в XLSX
Кнопка «Экспорт» матрицы SHALL скачивать XLSX в том же режиме, что и таблица: в режиме manual —
POST …/intercompany-matrix/manual/export с телом {debit_account_ids, credit_account_ids}, в режиме all —
GET …/intercompany-matrix/all/export; при выбранной одной стороне кнопка недоступна. Кнопка «Экспорт» результирующей таблицы
SHALL скачивать GET …/intercompany-matrix/result-table/export. Файл сохраняется под именем из Content-Disposition, при его
отсутствии — Шахматка_<ГК>_<год>_<квартал>.xlsx и Результирующая_таблица_ВГО_<ГК>_<год>_<квартал>.xlsx соответственно.
Пока идёт выгрузка, в состоянии загрузки только нажатая кнопка; ошибка API показывается уведомлением. Фильтр компаний, единицы и
знаки в запрос экспорта не передаются.
Scenario: Экспорт по всем счетам
- WHEN счета не выбраны и нажато «Экспорт» матрицы
- THEN отправлен
GET …/intercompany-matrix/all/export, браузер сохраняет файлintercompany-matrix_….xlsx
Scenario: Экспорт результирующей таблицы
- WHEN нажато «Экспорт» результирующей таблицы
- THEN отправлен
GET …/intercompany-matrix/result-table/export, кнопка «Экспорт» матрицы не переходит в состояние загрузки
Requirement: Полноэкранный режим
Кнопка «На весь экран» матрицы и результирующей таблицы SHALL переводить свой блок (панель фильтров и таблицу) в полноэкранный режим средствами Fullscreen API с белым фоном и таблицей на высоту окна; в нём кнопка меняется на «Свернуть». Выпадающие списки фильтров и подсказки SHALL оставаться видимыми в полноэкранном режиме. Выход клавишей Esc SHALL возвращать обычный вид и подпись кнопки. Отказ браузера войти в полноэкранный режим показывается уведомлением.
Scenario: Вход и выход
- WHEN нажато «На весь экран», затем Esc
- THEN блок разворачивается на весь экран, затем возвращается в страницу, кнопка снова «На весь экран»
Scenario: Фильтр в полноэкранном режиме
- WHEN матрица в полноэкранном режиме и открыт выбор «Компании»
- THEN выпадающее окно видно поверх полноэкранного блока