60 lines
6.7 KiB
Markdown
60 lines
6.7 KiB
Markdown
## Context
|
||
|
||
Реализация — PR RSHB/arm-core#141 (ветка `add-preset-shahmatka`). Шахматка — чистая функция от сводной ОСВ версии,
|
||
периметра и выбранных счетов; в БД не хранится (DECISION-5). Корректировки (`correction`) — хранимые ручные решения,
|
||
читаются, но в ядре пока никем не создаются.
|
||
|
||
## Decisions
|
||
|
||
1. Режим PRESET берёт правило по `rule_id`. Правило должно быть действительно для версии: при зафиксированном
|
||
`elimination_rules_version` — совпадать по `version_no`, иначе — иметь `valid_to IS NULL`; иначе 404.
|
||
2. Сторона дебета — `company_1`, если `side_1 = D`, иначе `company_2`; кредит — вторая сторона. Счета и исключения
|
||
раскрываются по иерархии (`_select_accounts`), как в MANUAL. Нет счетов хотя бы одной стороны — 422
|
||
`ACCOUNTS_REQUIRED`; неверные `side_1`/`measure`/`company_no` — 422 `INVALID_RULE`; не передан `rule_id` — 422
|
||
`RULE_REQUIRED`.
|
||
3. Показатель (`closing`/`turnover`) берётся из правила; ALL и MANUAL остаются на `closing`.
|
||
4. Применённые корректировки правила (`status = APPLIED`, тот же `rule_id` и версия консолидации) уменьшают
|
||
`amount_a` ячейки `(A, B)` на `debit_adjustment` корректировки (`legal_entity_id = A`, `counterparty_id = B`) и
|
||
`amount_b` на `credit_adjustment` корректировки `(B, A)`; расхождение, процент и порог пересчитываются, ID
|
||
корректировок попадают в `correction_ids_debit/credit`.
|
||
5. `unpaired-osv` строится из `one_sided`-ячеек шахматки пресета (`osv_entry_ids_*`) и возвращает строки сводной ОСВ,
|
||
содержащие эти записи.
|
||
6. `GET …/elimination-rules` отдаёт объект с основанием выбора версии; `as_of` не вводится.
|
||
7. xlsx пресета: имя `intercompany-matrix_<ГК>_<год>-<квартал>_v<n>_preset-<rule_id>.xlsx`, в шапке «Режим = Пресет»,
|
||
коды счетов сторон (отсортированы) и строка «Показатель» (Сальдо/Оборот) для всех режимов.
|
||
|
||
## Known issues / вопросы владельцу
|
||
|
||
Спека описывает фактическое поведение PR; пункты ниже не закреплены как окончательные и ждут решения автора и владельца.
|
||
|
||
1. При пустом `consolidation_version.elimination_rules_version` берутся текущие открытые правила. Это расходится с
|
||
DBML («фиксируется при первом расчёте, замораживается при VERIFIED») и критерием AURORA-1536; нужно решение
|
||
владельца, в том числе для версий в статусе `VERIFIED`.
|
||
2. «Актуальные» правила — `valid_to IS NULL` на сегодня, а не на отчётную дату консолидации.
|
||
3. Если открытыми остаются несколько `version_no`, список правил даёт дубли `rule_no`.
|
||
4. Семантика корректировки: `(rule, A, B)` дебетовой частью правит ячейку `(A, B)`, кредитовой — ячейку `(B, A)`;
|
||
`debit_account_id`, `credit_account_id` и `parent_correction_id` не учитываются; корректировки в ядре пока никто
|
||
не создаёт.
|
||
5. `unpaired-osv` построена на `one_sided` по наличию строк — это дефект AURORA-1651, и «без пары» здесь не равно
|
||
«без пары» по §5 и AURORA-1536.
|
||
6. Пресет здесь — правило Прил. 3, а §6 описывает пресеты как наборы счетов; PRESET по ОФР на оборотах
|
||
(`measure = turnover`) не подтверждён §5/§6.
|
||
7. Имя файла содержит UUID правила, шапка xlsx не содержит номер правила и версию; audit не пишет номер/версию правил
|
||
и ID применённых корректировок.
|
||
|
||
## Decisions made without discussion
|
||
|
||
- 2026-10-21. Change пишет ревьюер в ветке автора по решению владельца. Обоснование: автор не оформила OpenSpec. Цена
|
||
ошибки: автор переписывает change.
|
||
- 2026-10-21. Спека описывает фактическое поведение PR; спорное вынесено в Known issues. Обоснование: домен решает
|
||
автор и владелец, не ревьюер. Цена ошибки: после решения владельца спека меняется дельтой.
|
||
- 2026-10-21. Поле `as_of` удалено из `EliminationRulesOut` как мёртвое: после правок по ревью всегда `None`, в main
|
||
его не было, потребителей нет. Цена ошибки: если фронт ждал `as_of`, поле нужно вернуть.
|
||
- 2026-10-21. Интеграционный тест `test_preset_uses_current_rules_when_version_unfixed` приведён к фактическому
|
||
поведению (`version_no is None`, `is_version_fixed is False`), а не к старому ожиданию `version_no == rule.version_no`;
|
||
логика вычисления `version_no` не добавлялась. Цена ошибки: если автор решит возвращать номер версии, тест вернуть.
|
||
- 2026-10-21. mypy: `measure` аннотирован `Measure` без `cast`; слишком длинная f-строка имени файла свода ОСВ
|
||
(`consolidated_osv.py`) разбита на две без изменения результата (ruff E501). Цена ошибки: нулевая.
|
||
- 2026-10-21. В MODIFIED-блоке требования про правила элиминации и аудит экспорта приведён полный текст; требование
|
||
«XLSX шахматки» (ALL/MANUAL) не менялось, поведение PRESET описано отдельным ADDED-требованием.
|