# 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`; `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) — в 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|` независимо от знака в форме | Формы хранят знак по-разному (§7, §11.9); без единой конвенции Σ по компаниям и итоги неверны | Законно положительное значение строки расходов (сторно) станет отрицательным | | 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` не увидит вкладку — так и задумано матрицей |