Andrey Epifancev 1249e2ff3b feat(osv): сопоставление контрагента в сводной ОСВ — «Указать» → «Связать» по макету [32] (#14)
- ИНН-ячейка строк без сопоставления подсвечена, ссылка «Указать» рядом с ИНН из файла [32-osv-no-inn].
- Модалка «Выбор организации для связи с …» [32-osv-map-counterparty]: поиск с паузой 300 мс,
  scope group / весь справочник (от 3 символов), блок «Рекомендуемые», «Связать».
- POST …/osv/entries/{последняя entry_id}/counterparty; 409 ALIAS_TAKEN → перенос алиаса (move_alias),
  LOCK_REQUIRED → «Взять версию в работу?» → POST …/lock → повтор, LOCKED_BY_OTHER → имя держателя.
- После успеха перечитываются строки и сводка («Осталось N»).
- Чистые функции counterpartyMapping.ts + тесты; спека consolidated-osv-ui.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-08 17:39:23 +04:00

7.5 KiB
Raw Blame History

consolidated-osv-ui Specification

Purpose

Аналитик видит сводную ОСВ версии [30]: сводку с несопоставленными строками, пробелы по кварталам, таблицу с фильтрами в заголовках колонок и экспорт в xlsx; сопоставляет контрагента строки с ЮЛ справочника [32].

Requirements

Requirement: Сводка версии

Экран «Сводная ОСВ» [30] SHALL показывать шапку версии (ГК, период, номер, статус) и сводку GET /consolidations/versions/{id}/osv/summary: строк всего, документов, несопоставленных (unmapped_total — счётчик «Осталось N»; сопоставление — «Указать» в строке), автоматически сопоставленных.

Scenario: Контрольные цифры РБ 2024 Q3

  • WHEN открыт свод версии РБ 2024 Q3 после подтверждения 22 ОСВ из fixtures/osv/{rb,schastl}/2024-Q{1,2,3}
  • THEN «строк» = 1385, «документов» = 22, «несопоставленных» = 1381

Requirement: Таблица свода и фильтры

Экран SHALL показывать строки GET /consolidations/versions/{id}/osv постранично (размер страницы ≤ 2000): ЮЛ, счёт, контрагент, ИНН контрагента, сальдо на начало Дт/Кт, обороты Дт/Кт, сальдо на конец Дт/Кт (суммы — строками с разделителями разрядов) и последней колонкой «Тип контрагента» — бейдж ГСК (синий) / ГК (зелёный) / Внешний (серый), как в макете [30]. Фильтры — в заголовках колонок: ЮЛ (legal_entity_id), корень счёта (account_root), поиск по контрагенту (q, ≤ 500 символов), тип контрагента (counterparty_type, одно значение — на колонке «Тип контрагента»); только несопоставленные (unmapped) — кнопкой над таблицей. «Применить» и «Сбросить» SHALL закрывать окно фильтра. Смена фильтра SHALL перечитывать первую страницу.

Scenario: Строка из контрольных цифр

  • WHEN фильтр ЮЛ «Пекарня Счастливочная» и поиск «бисквит»
  • THEN строка 60.01 показывает сальдо нач. Кт 4 454 151.93, обороты Дт 128 058 143.65, Кт 125 950 450.77, сальдо кон. Кт 2 346 459.05, признак «ГСК»

Requirement: Ручное сопоставление контрагента

У строки без сопоставленного ЮЛ (counterparty_id = null) ячейка ИНН SHALL быть подсвечена и содержать ссылку «Указать» (рядом с ИНН из файла, если он есть), как в макете [32-osv-no-inn]. «Указать» SHALL открывать модалку «Выбор организации для связи с <имя контрагента из файла>» [32-osv-map-counterparty]: поиск, таблица ИНН / Организация / ГК / ГСК / ГСЗ / «Связать», рекомендуемые (recommended) — первыми под заголовком «Рекомендуемые» с зелёной подсветкой. Кандидаты — GET …/counterparty-candidates?scope=&entry_id=&q= с паузой 300 мс после ввода: по умолчанию scope=group (периметр и ГК); галочка «Искать во всём справочнике» — scope=all, при поиске короче 3 символов запрос не отправляется и показывается подсказка. «Связать» SHALL отправлять POST …/osv/entries/{entry_ids.at(-1)}/counterparty {legal_entity_id}, после успеха — сообщение (с кем связано, сколько записей ОСВ сопоставлено автоприменением, создан или перенесён алиас), закрывать модалку и перечитывать страницу свода и сводку («Осталось N» на клиенте не вычисляется). Ответы 409:

  • ALIAS_TAKEN — подтверждение «Имя уже закреплено за <владельцы>. Перенести?» → повтор с move_alias = true;
  • LOCK_REQUIRED — подтверждение «Взять версию в работу?» → POST …/lock → повтор; отказ — ничего не меняется;
  • LOCKED_BY_OTHER (от правки или от POST …/lock) — «Версию держит <имя>» (имя — из ответа POST …/lock или из lock карточки версии), без перехвата;
  • VERSION_NOT_EDITABLE и прочие ошибки — текстом сервера.

Scenario: Сопоставление «Пекарня Счастливочная ООО» в ОСВ РБ

  • WHEN в своде РБ 2024 Q3 у строки контрагента «Пекарня Счастливочная ООО» без сопоставления нажато «Указать» и у рекомендуемой «Пекарни Счастливочной» — «Связать» (версия не взята в работу → «Взять в работу»)
  • THEN строка показывает ЮЛ и тип «ГСК», «Осталось N» уменьшается на число сопоставленных строк, у ЮЛ появляется алиас

Scenario: Алиас занят

  • WHEN имя строки уже алиас другого ЮЛ и аналитик выбирает третье ЮЛ
  • THEN показан вопрос о переносе с именами владельцев; «Перенести» повторяет запрос с move_alias = true

Requirement: Пробелы

Экран SHALL показывать gaps[] сводки списком «ЮЛ — счёт — недостающие кварталы» с пояснением, что строки этих пар в своде отсутствуют.

Scenario: Пробелы РБ 2024 Q3

  • WHEN открыт свод версии РБ 2024 Q3
  • THEN показано 7 пробелов, у каждого недостающие кварталы «Q1, Q2»

Requirement: Экспорт

Кнопка «Скачать xlsx» SHALL получать GET /consolidations/versions/{id}/osv/export с текущими фильтрами через клиент API с токеном и сохранять файл; имя — из Content-Disposition, а если заголовок недоступен — Сводная_ОСВ_<ГК>_<год>_<квартал>.xlsx.

Scenario: Экспорт с фильтром

  • WHEN аналитик скачивает свод с фильтром по ЮЛ
  • THEN сохраняется xlsx, а ошибка сервера показывается текстом, а не скачивается