43 KiB
Raw Blame History

Design: расчёт КФО — правила §8, модель v5.26, контракт API

Change kfo-calculation-contract, issue RSHB/arm-ka-docs#206, ветка feat/206-kfo-contract. Читатели результата — Цыганков (AURORA-1546, расчёт), Степанов (AURORA-1547, экран на фейке). Читают как постановку, без созвона: документ должен отвечать на «что строить» сам.

1. Зачем

С 10.11.2026 в работу идут расчёт и экран КФО (Гант: разработка 10–16.11, тест заказчика 17–25.11). Сейчас у них нет опоры: §8 описывает КФО по прежней редакции, в модели не хватает колонок по компании, контракта API нет. Цель — к утру 09.11 дать три документа, по которым бэк и фронт стартуют параллельно и не расходятся.

Успех: Цыганков пишет расчёт по §8 и DBML, не спрашивая «а как тут»; Степанов строит экран по контракту на фейковых данных, и экран без правок подключается к настоящему бэку.

2. Цели, не цели, анти-цели

Цели

  • §8 «КФО» — полный алгоритм от форм и агрегатов до строки КФО, расхождений и порогов, с примерами.
  • DBML v5.26 — всё, что нужно хранить, чтобы отдать экран из kfo_result без пересчёта.
  • Контракт API КФО — чтение результата и сохранение ручных полей, md + OpenAPI 3.1.

Не цели — см. proposal.md «Non-goals» (код, ОФР-правила 1999, механизм пересчёта 1417, КФО Общий, подтверждение клиента, экспорт, проверки переходов, новые поля версии).

Анти-цели (провал, даже если документы формально готовы)

  • Решения заказчика выданы за принятые. Каждая развилка из «Что решить» DOC-274636 помечается: «на старте — вариант N, решает заказчик».
  • Сумма исключается дважды (автосумма + корректировка, обычный ББ-2 + гудвилл).
  • Контракт, который экран не может отрисовать без своих расчётов: фронт не считает ни долей, ни итогов, ни порогов.
  • Код роли или номер правила в бизнес-логике: поведение правила задаётся данными (elimination_mode), не rule_no.

3. Ограничения

  • Источник истины по полям — DBML; полей, которых нет в v5.26, в §8 и контракте нет.
  • Деньги — numeric(18,2), в API — строки с двумя знаками; float нет.
  • Производные консолидации не хранятся (DECISION-5); kfo_result(_line, _line_company) — хранимый результат версии, это разрешено моделью; агрегаты ВГО по-прежнему считаются на запрос.
  • Соглашения API — как в dev/api-contract-corrections.md §1 и dev/api-contract-goodwill.md §1 (префикс, права, 404 вне видимости, формат ошибок, порядок проверок правок, editable / read_only_reason).
  • Нумерация DBML. В docs открыт PR #203 (v5.25, метрики OCR, AURORA-1759). Наша версия — v5.26. Если #203 слит раньше нашего PR — строим v5.26 поверх v5.25. Если позже — v5.26 строим от v5.24 и в шапке пишем «v5.25 — PR #203»; второй слитый PR перед merge вливает изменения первого в свой файл (номера не переписываются задним числом).
  • Язык — русский, идентификаторы — английские.

4. Что решено

4.1 §8 «КФО» — содержание

Блок «КФО» §8 заменяется целиком; блоки «Корректировка», «Гудвилл», «Пороги», «Сравнение с КФО клиента» правятся только там, где противоречат новому блоку.

Единицы. Результат КФО хранится и отдаётся в тыс. руб. с двумя знаками. Суммы ОСВ и агрегатов — в рублях, переводятся в тысячи один раз на ячейке «в т. ч. взаимные» (компания × строка, см. «Округление»).

1. Строки. Бланк ББ и ОФР — полный вариант (full) той редакции, которую ядро выбирает по отчётной дате версии (как §11.9 и словарь имён ядра: ≤ 31.12.2024 — 66n, позже — fsbu4; contracts/statement-code-orders.yaml), наименования — словарь имён ядра. Для «Русского бисквита» на 01.10.2024 это 66н (1120, 1231, 2930 есть, 1105, 1215, 2420 нет). Плюс служебная строка GOODWILL (п. 8). Все строки бланка выводятся, даже нулевые. Строки форм компаний вне бланка в КФО не входят (предупреждение LINE_OUTSIDE_BLANK), строки без кода — тоже (решение 17.10.2026). На старте — вариант черновика (DOC-274636 вопрос 1): только бланк + гудвилл; решает заказчик.

2. «По данным клиента» (client_amount). По каждой компании периметра (consolidation_member) — подтверждённый (CONFIRMED) документ ББ / ОФР, привязанный к версии (consolidation_document). Колонка: ББ — на конец отчётного квартала, ОФР — за период с начала года по конец квартала (по дате колонки, не по is_current; так же, как УК гудвилла). Строки со статусом ok, повторы кода суммируются. Единицы формы — словарём единиц arm_statements → тыс. руб.: «тыс. руб.» как есть, «руб.» / 1000, «млн руб.» × 1000, до двух знаков ROUND_HALF_UP. Знак строк расходов. Формы разных компаний могут хранить расходы по-разному (§7, §11.9: скобки, минус или «без знака»). КФО приводит строки расходов бланка — 2120, 2210, 2220, 2330, 2350 — к одной конвенции: client_amount = −|значение|. Остальные строки — как в форме (1370, 2300, 2400 и прочие могут быть любого знака по существу).

  • нет формы → значения компании 0, предупреждение FORM_MISSING (вариант 1 вопроса 3 черновика; решает заказчик);
  • две и более подтверждённые формы одного типа → 0, FORM_AMBIGUOUS;
  • единицы не распознаны → 0, FORM_UNITS_UNKNOWN. КФО считается и при неполном комплекте (вопрос 17 черновика: вариант «считать, предупредить»).

3. Агрегаты. Источник взаимных сумм — агрегаты таблицы корректировок (§5 п. 2a, VgoService): тройка (правило, компания 1, компания 2) с суммами сторон amount_1, amount_2 (рубли) после ручных решений vgo_assignment. Нераспределённые строки ни в один агрегат не входят и в КФО не исключаются (предупреждение UNALLOCATED_ROWS с числом строк без отметки «не учитывать в КФО»). Тип отчётности агрегата — из правила. Отдельный обход ОСВ в КФО не делается: то, что видит аналитик в таблице корректировок, и есть вход КФО.

4. Исключения агрегата. Каждый агрегат даёт список исключений (компания, код строки, сумма в рублях ≥ 0). Если у агрегата есть применённая корректировка (correction.status = APPLIED) — п. 5, иначе автосумма по режиму правила (elimination_rule.elimination_mode):

Режим Автосумма Куда
min (ББ 3–8) min(amount_1, amount_2), если обе стороны > 0 и отклонение в допуске (§8 «Корректировка», порог как в коде, OQ-178); иначе 0 article_1_line у компании 1, article_2_line у компании 2
min_or_full (ББ 2, новое) обе стороны > 0 → min(amount_1, amount_2); сторона 2 = 0 → amount_1; сторона 1 = 0 → 0. Порога нет (DOC-274230 правило 2) компания 1 — article_1_line; компания 2 — каскад по кодам article_2_line
manual (ББ 1) 0 — только корректировка —
режимы ОФР по правилам AURORA-1999 (§5); до неё агрегатов ОФР нет по правилу

Каскад (составная статья «a/b/c»): сумма снимается со строки a компании в пределах её доступного остатка («по данным клиента» строки в рублях минус уже снятое с неё другими агрегатами, но не ниже 0), остаток — со строки b, затем c; что не уместилось — целиком на последнюю строку (DOC-274230: «если остаётся положительный остаток, он исключается из строки 1370»). Агрегаты обходятся в порядке rule_no, затем ИНН компании 1, затем ИНН компании 2 — порядок детерминирован. Каскад применяется и к составной статье в корректировке, если в ней код с «/» (в коде корректировки код один, поэтому на практике — только автосумма правила 2).

Изменения seed правил ББ (в AURORA-1546, arm-core/api/seed/core/elimination_rules_v1.yaml): правило 2 — elimination_mode: min_or_full, article_2_line: "1310/1350/1370"; правка версии 1 на месте, без новой версии правил (п. 6 «Decisions»).

Автосумма — одна функция для таблицы корректировок и КФО. Сейчас correction_source.py знает только manual и «остальное как min»; с min_or_full таблица корректировок показала бы правило 2 с порогом 5 % и односторонний агрегат нулём, а КФО исключил бы иначе. Поэтому этот PR правит и §8 «Корректировка», и dev/api-contract-corrections.md: у агрегата min_or_full eliminated_amount = автосумма по таблице выше, exceeds_threshold = false всегда, статус — AUTO при обеих сторонах, ONE_SIDED с eliminated_amount = amount_1 при пустой стороне 2. Код — в AURORA-1546: автосумма агрегата выносится в одну функцию домена, её вызывают и correction_source, и расчёт КФО. Правило 1 остаётся manual: по DOC-274230 обе его суммы — у компании 2 (Кт 76.7.1 − Дт 76.7.9), а сторона агрегата устроена «компания 1 — дебет, компания 2 — кредит»; автосумма правила 1 — после переработки seed (follow-up), сейчас только корректировкой.

5. Корректировка агрегата заменяет автосумму. Применённая корректировка агрегата отменяет его автосумму целиком и не прибавляется к ней (DOC-274636 допущение 4; DOC-272613: сохранённые корректировки не меняют суммы сторон). Исключения: компания 1 — статьи debit[] (основная + дочерние), компания 2 — credit[], суммы как введены. Если заполнены обе стороны и итоги сторон разные, каждая сторона исключает меньший итог (ответ Лысенко п. 8, §8 «Корректировка»): снимается со статей стороны по порядку — основная, затем дочерние в порядке ввода — до исчерпания. Пустая сторона ничего не исключает, а другая — как введена (одностороннее правило 1, ОФР 1/2/3).

6. «В т. ч. взаимные» по компании (vgo_amount). Σ исключений компании по строке в рублях → тыс. руб., до целых тысяч, половина — от нуля (ROUND_HALF_UP по модулю), со знаком строки: строки расходов (2120, 2210, 2220, 2330, 2350; после приведения п. 2 они ≤ 0) получают отрицательное vgo_amount. Так на всех строках одно равенство: cleaned_amount = client_amount − vgo_amount, исключение всегда приближает значение к нулю (при превышении — проходит через ноль). На старте — вариант 1 вопроса 8 черновика (округление ячейки); решает заказчик.

7. Строка КФО. По компании: client_amount, vgo_amount, cleaned_amount, share_percent = cleaned / bank_amount × 100 (хранится 4 знака, отдаётся 2; bank_amount = 0 → null). По строке: sum_amount = Σ client, vgo_amount = Σ vgo по компаниям (= eliminated_auto + eliminated_manual, где auto — от агрегатов без корректировки, manual — от агрегатов с корректировкой; гудвилл-пары — в auto), goodwill_adjust (у GOODWILL и у итогов, куда он входит), bank_amount = sum_amount − vgo_amount + goodwill_adjust.

Итоговые строки (1100, 1200, 1300, 1400, 1500, 1600, 1700, 2100, 2200, 2300, 2400, 2500): «по данным клиента» — итог из формы компании, «в т. ч. взаимные» — Σ vgo_amount слагаемых по формуле бланка с их знаками (1100 ← 1110…1190; 1600 ← 1100 + 1200; 1700 ← 1300 + 1400 + 1500; 2100 ← 2110 + 2120; 2200 ← 2100 + 2210 + 2220; дальше по бланку); очищенные — разность. Гудвилл в итогах: goodwill_adjust итоговой строки = Σ goodwill_adjust её слагаемых, то есть G у 1100 и 1600; разреза по компаниям у этой части нет, поэтому bank_amount итога = Σ очищенных компаний + goodwill_adjust, а доли компаний у 1100/1600 считаются от bank_amount и в сумме дают меньше 100 % на долю гудвилла. Проверка сходимости: bank(1600) = bank(1700), если сходятся формы компаний (у ГО −ФВ, у ДО −P, гудвилл +G, ФВ − P = G). Итог КФО совпадает с подписанным клиентом минус взаимные, а не с суммой своих строк (вариант 2 вопроса 7 черновика; решает заказчик). Пример: 10 млн исключены из 2110 «Альфы» и 2120 «Беты» — у 2100 каждой компании vgo ±10 000, у строки 2100 КФО Σ vgo = 0, валовая прибыль группы не меняется.

8. Гудвилл (DOC-259025, §8 «Гудвилл»). Ветка гудвилла идёт по паре ГО → ДО таблицы гудвилла, независимо от агрегатов: для пары с use_goodwill (действующая, отмечена, доля и комментарий, G > 0) при goodwill_enabled у версии — исключения ГО 1170 на ФВ (как в таблице гудвилла — все строки 58.01 и потомков пары), ДО 1310 на P (без каскада), G — в строку GOODWILL; агрегат правила 2 той же пары (компания 1 = ГО, компания 2 = ДО), если он есть, не применяется — ни автосумма, ни корректировка. Если строку 58.01 этой пары аналитик перенёс в другое правило или отметил «не учитывать», она всё равно входит в ФВ — предупреждение GOODWILL_ROW_REASSIGNED: ВГО по ней могут исключиться дважды, решает аналитик. При G ≤ 0 или выключенном гудвилле — обычный агрегат (п. 4–5). Строка GOODWILL — раздел I, сразу после 1170, без разреза по компаниям, goodwill_adjust = bank_amount = Σ G применимых пар в тыс. руб. (до целых тысяч); входит в итоги 1100 и 1600; kfo_result.goodwill_total — то же значение. Место строки: по DOC-259025 (R-1) — отдельная строка раздела I; макет [31-04] показывает «В т.ч. Гудвилл» под 1170 — расхождение в открытых вопросах, решают методологи.

9. Расхождения по статьям. По агрегатам режима min (ББ и ОФР): |amount_1 − amount_2| — на статью стороны с большей суммой (компания 1 — article_1_line, компания 2 — article_2_line), независимо от корректировок (вариант 1 вопроса 10 черновика; решает заказчик). Агрегаты manual, min_or_full и гудвилл-пары в расхождения не входят. По строке — Σ в рублях → тыс. руб. до целых. total_deviation_bb / total_deviation_ofr — Σ по строкам своего отчёта. has_deviations — хотя бы одна строка ≠ 0.

10. Пороги (ТЗ 6.8, DOC-274636 правило 8; величины — КФО банка, тыс. руб.):

  • ББ: ЧА = строка 1300 (вопрос 11, вариант FNR03), ВБ = 1600. ЧА ≥ 10 % ВБ → база ЧА, предел 10 % ЧА; иначе (в том числе ЧА ≤ 0) → база ВБ, предел 1 % ВБ.
  • ОФР: 2200 ≥ 0 и 2200 / 2110 ≥ 10 % → база 2200, предел 10 % 2200; иначе → база 2110, предел 1 % 2110. 2110 = 0 → база 2110, предел 0.
  • Превышение — total_deviation > предел (равно — норма). Процент расхождения от базы — для сводки; база = 0 → null.
  • Превышение хотя бы по одному отчёту → нужно обоснование (threshold_justification). Обязательность перед отправкой на верификацию (вариант 2 вопроса 13) проверяет переход статуса — AURORA-2002 / 1414, не КФО.

11. Реквизиты формы (ТЗ 6.4, DOC-274636 правило 9): ГК, ГСК, отчётная дата, номер и статус версии, сценарий, подход (approach — пакет документов), гудвилл учтён да/нет и сумма, расхождения ББ/ОФР и превышения, обоснование, корректировки (число агрегатов с применённой корректировкой и Σ их исключений по типу отчёта), причины отклонений от Методики (consolidation_version.methodology_deviations, ввод на вкладке), решение УОБ (номер, дата — только чтение). «Подход по Методике» и «согласовано клиентом» — не делаем до ответа заказчика (вопросы 14, 15).

12. Пересчёт и заморозка. Результат хранится у версии (kfo_result, одна запись). Пока версия не заморожена, чтение отдаёт результат по текущим данным версии: если входы изменились после computed_at, сервер пересчитывает и сохраняет до ответа (как обнаруживать изменения — AURORA-1417). Кнопки «Рассчитать» нет (вариант 1 вопроса 16). Комментарии строк и обоснование переносятся при пересчёте по (тип отчёта, код строки). При «Верифицирован» is_frozen = true (ставит AURORA-2002) — дальше результат только читается.

Предупреждения — {code, message, legal_entity_id?, statement_type?, count?}, не блокируют расчёт: FORM_MISSING, FORM_AMBIGUOUS, FORM_UNITS_UNKNOWN, LINE_OUTSIDE_BLANK, UNALLOCATED_ROWS, INCOME_RULES_MISSING (до 1999 — агрегатов ОФР нет, взаимные обороты = 0), GOODWILL_NOT_APPLIED (гудвилл включён, а применимых пар нет), GOODWILL_ROW_REASSIGNED (п. 8). Предупреждения и сводка корректировок (п. 11) — часть результата: хранятся в kfo_result и пишутся при расчёте, чтобы замороженная версия отдавала ровно то, что видели при верификации.

§8 содержит сквозной пример: две компании, правила 2 (с гудвиллом и без), 6 (в допуске и с корректировкой), ОФР-пара 2110/2120, итоги 1100/1600/2100, пороги — числа сходятся до тысячи. Плюс прогон на «Русском бисквите» 01.10.2024 (эталон Консолидация_Группа РБ.xlsx) — как критерий 1546, с известными расхождениями: алгоритм по ТЗ (min, порог 5 %), а эталон исключает каждую сторону полностью (OQ-155).

4.2 DBML v5.26

  • kfo_result_line_company: + client_amount numeric(18,2) («по данным клиента», тыс. руб.), + vgo_amount numeric(18,2) («в т. ч. взаимные», со знаком строки); amount — пояснение «очищенные показатели»; share_percent numeric(7,4) — «4 знака хранения, в API 2». Строка GOODWILL разреза не имеет.
  • kfo_result_line: пояснения по §8 — единицы тыс. руб.; sum_amount = Σ client; eliminated_auto / eliminated_manual — от агрегатов без / с корректировкой, не складываются по одному агрегату; vgo_amount = auto + manual; goodwill_adjust — у GOODWILL и итогов 1100/1600 (решение #12); consolidated_amount = sum − vgo + goodwill_adjust; deviation_amount — п. 9; comment ≤ 2000, переживает пересчёт; source_kind — всегда balance (ОСВ как источник — вопрос 3).
  • kfo_result: пояснения порогов по п. 10, goodwill_total по п. 8, is_frozen — ставит переход «Верифицирован».
  • kfo_result: + warnings jsonb (массив предупреждений расчёта, п. 12), + corrections_count_bb int, corrections_count_ofr int, corrections_amount_bb numeric(18,2), corrections_amount_ofr numeric(18,2) (число агрегатов с применённой корректировкой и Σ их исключений в тыс. руб., п. 11).
  • audit_action: + KFO_EDIT — сохранение ручных полей КФО (комментарии строк, обоснование порога, причины отклонений от Методики) одним событием на запрос, object_type = kfo_result, before / after по изменённым полям; раздел — KFO (в audit_section он есть; исполнение плана, R-1 ledger). Миграция enum — в 1546.
  • elimination_rule.elimination_mode: в пояснение — значение min_or_full (varchar, миграция схемы не нужна).
  • Шапка — changelog v5.26; entities-v5.26.md — копия с теми же правками; ссылки «v5.24» в CLAUDE.md workspace и openspec/config.yaml — на v5.26.
  • Миграция arm-core (семь колонок nullable — две в kfo_result_line_company, пять в kfo_result — и значение audit_action) — в AURORA-1546.

Разреза «расхождение по компании» не добавляем: на экране «Расхождения» — общая колонка строки.

4.3 Контракт API (dev/api-contract-kfo.md + .openapi.yaml)

Префикс /api/v1/consolidations/versions/{version_id}.

Метод и путь Право Ответ Ошибки
GET …/kfo KFO_VIEW 200 KfoResultOut 404 NOT_FOUND
PUT …/kfo/annotations CONSOLIDATION_EDIT 200 KfoResultOut 404, 409 VERSION_NOT_EDITABLE / LOCK_REQUIRED / LOCKED_BY_OTHER, 422 UNKNOWN_LINE, 422 pydantic

Чтение — по KFO_VIEW (право есть в seed и означает ровно это), не по CONSOLIDATION_VIEW, как корректировки и гудвилл; правка — CONSOLIDATION_EDIT (KFO_EDIT в seed нет).

KfoResultOut:

  • version_id, computed_at, is_frozen, editable, read_only_reason, units = "thousand_rub";
  • companies[] — {legal_entity_id, name, inn} в порядке колонок (по имени);
  • requisites — п. 11;
  • summary.balance / summary.income — {deviation_total, base_kind (NET_ASSETS | BALANCE_TOTAL | SALES_PROFIT | REVENUE), base_amount, limit_percent, limit_amount, deviation_percent, exceeded};
  • justification_required, threshold_justification;
  • goodwill — {enabled, total};
  • balance.lines[], income.lines[] — KfoLineOut: line_code, line_name, ordinal, is_total, is_threshold_base (подсветка строки базы при превышении), companies[] {legal_entity_id, client_amount, vgo_amount, cleaned_amount, share_percent} (у GOODWILL — пусто), sum_amount, vgo_amount, eliminated_auto, eliminated_manual, goodwill_adjust, bank_amount, deviation_amount, comment;
  • warnings[].

Деньги — строки с двумя знаками в тыс. руб. (в отличие от корректировок и гудвилла, где рубли: результат КФО по определению в тысячах; поле units явно). Переключатели «Единицы» (тыс. / млн) и «Знаков после запятой» — только показ на фронте.

PUT …/kfo/annotations — тело {comments?: [{statement_type, line_code, comment | null}], threshold_justification?, methodology_deviations?}; отсутствующее поле не меняется, null — очищает; комментарий ≤ 2000, обоснование и причины ≤ 4000; строки нет в бланке — 422 UNKNOWN_LINE. Сохраняет набором в одной транзакции, аудит — KFO_EDIT (4.2). Ответ — полный KfoResultOut.

Состояния экрана из DOC-274647 выражаются полями ответа: нет компаний / нет форм — warnings; заморожено — is_frozen

  • editable = false. Примеры ответа (обычный, с превышением и гудвиллом, замороженный) — в md и в examples OpenAPI, на числах сквозного примера §8; Степанов берёт их как фейк.

4.4 Вложения в Jira

После открытия PR (не дожидаясь merge): AURORA-1546 — 05-domain-rules.md (§8) и data-model-v5.26.dbml; AURORA-1547 — api-contract-kfo.md и api-contract-kfo.openapi.yaml; в обеих — комментарий со ссылкой на PR. После правок по ревью — новые версии вложений.

5. Что остаётся исполнителю плана

Точный перечень и порядок строк бланка (из словаря ядра и statement-code-orders.yaml), тексты предупреждений, формулировки §8, разметка OpenAPI (имена схем, examples), числа сквозного примера, расстановка открытых вопросов в 07-open-questions.md (новые OQ с номерами по порядку).

6. Decisions made without discussion

# Дата Решение Обоснование Цена ошибки
1 06.11.2026 Развилки «решает заказчик» из DOC-274636 закрываются вариантом черновика как стартовым, с пометкой Раскладка спринта 4, R-2; иначе 1546 не стартует Доработка по ответу заказчика
2 06.11.2026 Вход КФО — агрегаты таблицы корректировок (§5 п. 2a), не отдельный обход ОСВ Одна истина для аналитика и КФО; двойной учёт уже снят разнесением Если заказчик захочет КФО «мимо» разнесения — переделка источника
3 06.11.2026 Корректировка агрегата заменяет автосумму; при разных итогах сторон каждая исключает меньший DOC-274636 доп. 4, ответ Лысенко п. 8 Неверная сумма ВГО на агрегатах с корректировкой
4 06.11.2026 Правило 2 считается автоматически по DOC-274230 (режим min_or_full, каскад 1310 → 1350 → 1370) правкой seed версии 1 на месте Описание 1546 (владелец, 06.11) требует каскада; верифицированных версий нет — объяснимость старых результатов не страдает Версии, созданные до правки, начнут считать правило 2 по-новому; если где-то это недопустимо — нужна версия правил 2
5 06.11.2026 Правило 1 остаётся ручным (только корректировка) Обе суммы DOC-274230 — у компании 2, сторона агрегата устроена иначе; переделка seed не влезает ВГО по 76.7.x не исключаются без корректировки аналитика
6 06.11.2026 Результат КФО в API — в тыс. руб. (поле units), не в рублях, как в других контрактах Округление до тысяч — часть расчёта; рубли из результата не восстановить Фронт, привыкший к рублям, неверно масштабирует — снимается полем units
7 06.11.2026 vgo_amount со знаком строки; cleaned = client − vgo на всех строках Расходы в формах с минусом; одно равенство без исключений для экрана и итогов Если формы хранят расходы положительными — знак у 2120/2210/… перевернётся (проверить на фикстурах в 1546)
8 06.11.2026 Строка GOODWILL — отдельная строка раздела I после 1170, без разреза по компаниям, входит в 1100/1600 DOC-259025 важнее макета (R-1); разрез по компаниям гудвиллу не определён Если методологи выберут «в т. ч. под 1170» — перенос строки и пересчёт итогов
9 06.11.2026 Чтение пересчитывает устаревший результат сам; кнопки «Рассчитать» нет Вариант 1 вопроса 16; фронту не нужно знать про устаревание Долгий GET на больших версиях — оптимизация в 1417
10 06.11.2026 Разреза «расхождение по компании» в модели нет (в чате обещал добавить) На экране «Расхождения» — общая колонка строки Понадобится расшифровка расхождения по компании — новая колонка
11 06.11.2026 Порядок обхода агрегатов для каскада — rule_no, ИНН компании 1, ИНН компании 2 Детерминированный результат при нескольких агрегатах на одну строку Иное распределение между 1310/1350/1370 при нехватке остатка
12 06.11.2026 Гудвилл в итогах — goodwill_adjust у 1100/1600 = Σ слагаемых (вопрос ревью 1, вариант «а») Одна формула bank = sum − vgo + goodwill_adjust на всех строках; 1600 сходится с 1700 Доли компаний у 1100/1600 в сумме < 100 % — если смутит заказчика, показывать долю гудвилла отдельно
13 06.11.2026 Строки расходов 2120, 2210, 2220, 2330, 2350 приводятся к `− x ` независимо от знака в форме
14 06.11.2026 Автосумма агрегата — одна функция для таблицы корректировок и КФО; PR правит §8 «Корректировка» и контракт корректировок под min_or_full Иначе аналитик видит одно, а КФО исключает другое Шире PR и 1546 (правка correction_source.py)
15 06.11.2026 Предупреждения и сводка корректировок хранятся в kfo_result (warnings jsonb, 4 колонки) Замороженная версия должна отдавать то, что видели при верификации Лишние колонки, если ЕХ всё равно заморозит ответ целиком в срез
16 06.11.2026 Аудит ручных полей КФО — новое действие KFO_EDIT В audit_action подходящего нет; инвариант «append-only аудит» Если заказчику нужен отдельный раздел журнала — новое значение раздела
17 06.11.2026 Бланк — по редакции на отчётную дату версии (66н ≤ 2024, ФСБУ 4 позже) Иначе КФО за 2024 теряет статьи 66н; так же выбирает редакцию ядро Версия на стыке редакций с формами разных редакций — строки вне бланка в предупреждения
18 06.11.2026 Гудвилл-ветка — по паре таблицы гудвилла, независимо от агрегатов; агрегат правила 2 пары подавляется; перенос строки 58.01 — предупреждение ФВ гудвилла уже определён по всем строкам 58.01 пары (контракт гудвилла) Двойное исключение строки, перенесённой аналитиком в другое правило, — видно по предупреждению
19 06.11.2026 Чтение КФО — по KFO_VIEW, правка — по CONSOLIDATION_EDIT KFO_VIEW в seed есть и означает ровно это; KFO_EDIT нет Роль с CONSOLIDATION_VIEW без KFO_VIEW не увидит вкладку — так и задумано матрицей
20 06.11.2026 У итоговых строк deviation_amount = null Сумма расхождений актива и пассива в итоге бессмысленна; сводка считается по строкам бланка Экрану нужна сумма раздела — добавить на фронте (ledger, Task 1)
21 06.11.2026 Примеры контракта: гудвилл + превышение, гудвилл выключен, заморожено; примера «норма» нет Все три — одна версия сквозного примера, в ней превышение У фронта нет зелёной сводки в фейке — подменить exceeded руками (ledger, Task 1)
22 06.11.2026 KFO_EDIT — раздел журнала KFO, не CONSOLIDATION audit_section.KFO в модели есть и точнее Фильтр журнала «Консолидация» не покажет правки КФО (ledger, Task 2)
23 06.11.2026 OpenAPI КФО генерируется scripts/kfo_contract/gen_kfo_openapi.py из kfo_example.py, руками не правится Числа примеров совпадают с §8; проверки правил в одном месте Правка руками разойдётся с генератором при следующей перегенерации (ledger, Task 3; ревью M-9)
24 06.11.2026 Порядок исключений: гудвилл-пары, затем агрегаты; остаток для каскада уменьшают все исключения Ревью I-1: иначе распределение 1310/1350/1370 у ДО с несколькими ГО зависит от реализации Иное распределение между 1310/1350/1370, если методологи считают иначе
25 06.11.2026 Округляется одна ячейка: vgo и manual — до тысяч, auto = vgo − manual Ревью I-2: раздельное округление ломает vgo = auto + manual auto может отличаться на 1 тыс. от «своей» суммы в рублях
26 06.11.2026 min_or_full при amount_2 ≤ 0 — как пустая сторона (amount_1), при amount_1 ≤ 0 — 0; расхождения — по всем агрегатам min, в том числе односторонним Ревью I-3; односторонний остаток — тоже неисключённое ВГО (вариант 1 OQ-186) Порог срабатывает чаще из-за односторонних агрегатов
27 06.11.2026 share_percent при ` доля ≥ 1000 %—null(колонкаnumeric(7,4)` не расширяется)
28 06.11.2026 Итоги — слагаемые с +1 после приведения знака; формулы §7 с минусом к КФО не применяются; 2410/2411 — как в форме (OQ-12); итога нет в форме (упрощённая) — Σ слагаемых Ревью I-5, I-6 Σ строки 2410 по компаниям с разной конвенцией знака неверна (на итоги не влияет — итоги из формы)
29 06.11.2026 Корректировка агрегата правила 2, закрытого гудвилл-парой, не применяется и не входит в сводку; предупреждение CORRECTION_SUPERSEDED_BY_GOODWILL Ревью M-5: аналитик видит её в таблице корректировок, а КФО игнорирует Лишнее предупреждение, если аналитик ввёл её намеренно