6.9 KiB
Raw Blame History

Why

AURORA-1746 и замечание заказчика (Циликов А.В., 23.10.2026, строка 10 чек-листа, AURORA-1865): «при загрузке ОСВ без ИНН необходимо сопоставить все организации без ИНН… нужно, чтобы система несопоставленные организации считала внешними и позволяла формировать консолидацию без прокликивания каждой».

Расчёт уже так работает: несопоставленный контрагент — «Внешний» (§3 п. 5), переход к шахматке не блокируется (решение заказчика 16.10.2026, AURORA-1388). Ощущение обязательности создают баннер над сводом «Для перехода к следующему шагу сопоставьте все внешние организации без ИНН» и модалка [31-00], которая всплывает при каждом уходе с «ОСВ», пока unmapped_total > 0. Счётчик до нуля на реальных данных не доходит: в него попадают зарплата, подотчётные лица и прочие строки без организации.

Для шахматки важны не все строки без ИНН, а только те, где прячется участник периметра. Признак этого — пара участников, где у одного есть записи с другим, а у другого встречных записей нет. Такие пары и нужно показать аналитику перед шахматкой, с местом для разбора (решение владельца 27.10.2026).

What Changes

Репозиторий — arm-core (api/, web/). Срез 4 (сводная ОСВ), доработка. Правило — 05-domain-rules.md §3 п. 9 (отдельный PR в docs).

  • Ядро. Чистая функция «пары без встречных записей» в domain/consolidated_osv.py: для участников периметра А ≠ Б пара (А, Б) — у А есть строка свода с counterparty_id = Б, у Б нет строки с counterparty_id = А. GET …/osv/summary отдаёт список counter_pairs[]; GET …/osv и экспорт получают фильтр counterparty_id. Ничего не хранится.
  • Фронт, режим «Встречные записи». Над сводом — переключатель «Свод | Встречные записи (N)». Во втором режиме: сверху список пар, под ним две таблицы на всю ширину: строки А с контрагентом Б и строки Б без ИНН и без сопоставления с «Указать» (та же модалка сопоставления, что в своде).
  • Фронт, модалка перед шахматкой. Вместо [31-00] «Остались неуказанные ИНН» — «Нет встречных записей: N пар у M участников», кнопки «Показать пары» / «Остаться» / «Перейти». Показывается при уходе с «ОСВ», если пары есть, один раз на версию за сессию браузера и снова — если список пар изменился. Строки без ИНН сами по себе модалку не вызывают.
  • Фронт, баннер. Текст без «сопоставьте все»: несопоставленные учитываются как внешние; счётчик «Осталось: N» и кнопка «Показать ЮЛ без ИНН» остаются.

Non-goals

  • Подсветка строки-кандидата у Б по совпадению суммы с зеркальной суммой у А (правила элиминации) — отдельная задача.
  • Хранение решения аналитика «встречных записей нет, это пропуск в учёте» — в БД ничего не пишется (решение владельца 27.10.2026); DBML не меняется.
  • Отсев строк, не являющихся организациями (зарплата, подотчётники), из счётчика unmapped_total.
  • Сверка по счетам и суммам внутри пары — это делает шахматка (§6).
  • Поиск участника, ошибочно сопоставленного с другим ЮЛ: справа показываются только несопоставленные строки без ИНН.
  • Строки Б с ИНН из файла, которого нет в справочнике (старый ИНН, опечатка): по решению 08.10.2026 они не требуют сопоставления, в правую таблицу не попадают, и такая пара из режима не закрывается. Оставлено как есть (решение владельца 27.10.2026), разбор — отдельная задача Jira; модалка и пустое состояние называют эту причину.

Capabilities

New Capabilities

Modified Capabilities

  • consolidated-osv: ADDED «Пары участников без встречных записей»; MODIFIED «Страница свода и сводка» (фильтр counterparty_id, counter_pairs[] в сводке).
  • consolidated-osv-ui: ADDED «Режим «Встречные записи»», ADDED «Баннер строк без ИНН».
  • consolidations-ui: REMOVED «Предупреждение «Остались неуказанные ИНН»»; ADDED «Предупреждение «Нет встречных записей»».

Impact

  • Таблицы DBML v5.23 — только чтение: consolidation_member, osv_entry, legal_entity, consolidation_document.
  • api/src/domain/consolidated_osv.py, api/src/services/consolidated_osv.py, api/src/schemas/consolidations.py, api/src/api/endpoints/consolidations/osv.py (+ export), тесты api/tests/.
  • web/src/widgets/ConsolidatedOsvContent/, web/src/widgets/ConsolidatedOsv/ (OsvTabs.tsx, новый режим), web/src/layouts/ConsolidationReportPage.tsx, web/src/utils/consolidations.ts, web/src/services/api/osv.ts, web/src/types/api.ts.
  • Документация: ../docs/context/05-domain-rules.md §3 п. 9, ../docs/context/10-user-journey.md (строка 3.1), ../docs/dev/api-contract-slice-4.md — отдельный PR в docs.