diff --git a/context/05-domain-rules.md b/context/05-domain-rules.md index fde46f1..236c4e1 100644 --- a/context/05-domain-rules.md +++ b/context/05-domain-rules.md @@ -495,7 +495,10 @@ closing_* = closing_* строки Qn ## §4. Правила элиминации — пары счетов (Прил. 3 ТЗ, DOC-223044, FNR03) Хранятся как данные: `elimination_rule` (+ `elimination_rule_account`), версионируются; версия фиксируется в -`consolidation_version.elimination_rules_version`. Seed-набор для ББ (`statement_type = balance`, `measure = closing`): +`consolidation_version.elimination_rules_version`. Для версии консолидации берётся версия правил, **действующая на дату +составления консолидации** (создания версии), а не на её отчётный период; фиксируется при создании версии или первом +расчёте, не в GET-запросе (OQ-174, решение владельца 21.10.2026; реализация — AURORA-1536). Пока поле пусто, расчёты +берут открытые правила (`valid_to IS NULL`). Seed-набор для ББ (`statement_type = balance`, `measure = closing`): | № | Статья А (Дт) | Счета А (closing_debit) | Статья Б (Кт) | Счета Б (closing_credit) | mode | Примечание | |---|---|---|---|---|---|---| @@ -591,7 +594,13 @@ closing_* = closing_* строки Qn ## §6. Шахматка и результирующая таблица (DOC-221277) Вход: версия + набор дебетовых счетов (`kind ∈ A, AP`) и кредитовых (`kind ∈ P, AP`); предустановки: «58.03 vs -67.03 + 66.03», «60 + 62 + 76 vs 60 + 62 + 76», «все счета». +67.03 + 66.03», «60 + 62 + 76 vs 60 + 62 + 76», «все счета». Дополнительно пресетом может быть **правило ББ из §4** +(`statement_type = balance`): дебетовые и кредитовые счета берутся из сторон правила (с исключениями `is_excluded`), +показатель — `measure` правила (у всех правил ББ seed v1 — `closing`); каскада §5 нет — это просмотр сумм по счетам правила, не сумма элиминации (решение владельца +21.10.2026, arm-core #141). Правила ОФР пресетом не являются (ОФР в §4 открыт). + +Шахматка — суммы первички: корректировки (§8) в ячейках не учитываются, список «строк без пары» шахматка не даёт — +строки ОСВ ячейки — AURORA-1653 (`osv_entry_ids_*` ячейки), строки без пары — упаковка §5 п. 2 (AURORA-1536). Строки/столбцы — компании периметра; диагональ пуста. ``` diff --git a/context/07-open-questions.md b/context/07-open-questions.md index a2ad3c4..ee9134a 100644 --- a/context/07-open-questions.md +++ b/context/07-open-questions.md @@ -179,3 +179,4 @@ | OQ-171 | Вид субконто «Организации» в строке между названием ведомости и периодом (файл-письмо «ОСВ сч. 60 за 2 кв. 2026», план счетов ООО Хреновская Нива): что это за вид в 1С — организации-контрагенты (справочник «Организации» или «Контрагенты» под другим названием) или собственные организации учёта; на каких счетах встречается | tabular-parser #59, change `osv-flat-form` (R-10, решение сессии при одобрении запуска 19.10.2026) | §1.1 (синоним в `osv_groups.yaml`), сопоставление контрагентов | открыт; допущение принято: синоним `COUNTERPARTY` — только множественное число «Организации» (`^организации\b`, R-17); единственное «Организация» (собственная организация учёта в шапке) остаётся `OTHER`; другой смысл «Организации» на иных счетах даст `COUNTERPARTY` вместо `OTHER`, виден по предупреждениям | | OQ-172 | Безымянная аналитика первого уровня на счёте **63** (резервы по сомнительным долгам) в плоской форме без названия вида: на файлах контура таких строк нет; 51 строка — в fixtures, golden `osv-dkb/nm/2025-Q3/НМ_ОСВ_63_Контрагенты_…json` (имя файла «63_Контрагенты» — довод за включение 63); счёт 63 не входит в `counterparty_accounts` (§1.3), строки остаются `OTHER` без имени. Нужен ли 63 в списке (аналитика резерва — контрагенты-должники) | tabular-parser #59, приёмка Task 6 (19.10.2026) | §1.3, сопоставление контрагентов | открыт; допущение принято: 63 в список не входит, строки `OTHER` | | OQ-173 | Пересечение правил в сумме элиминации: счета сторон правил §4 пересекаются — дебет № 5–8 (76 у № 5; 60/62/76 у № 6–8), кредит: 67.03 (№ 3 и маска 67 у № 7), 66.03 (№ 4 и маска 66 у № 8), 66.04/67.04 (№ 5 и № 7/8). Строка такого счёта входит в Σ стороны каждого правила, и сумма min(ΣA, ΣB) по правилам может превысить Σ самой стороны — двойная элиминация. Считать ΣA правила только по строкам, которые упаковка (§5 п. 2) отнесла к этому правилу? Или распределять сторону по правилам в фиксированном порядке? | решение по OQ-07 (docs #136, 19.10.2026), описание AURORA-1536 | §5 п. 1, AURORA-1536, КФО (§8 `eliminated_auto`) | **закрыт решением владельца 19.10.2026 (docs #136):** каскад по остатку — правила пары (A, B) считаются по порядку `rule_no` (в Прил. 3 он уже от частного к общему: № 3/4 раньше № 7/8, № 5 раньше № 6, № 6 → 7 → 8), каждое берёт min из остатка сторон после предыдущих, как в правиле № 1 Прил. 3 («сначала из 1450 до обнуления…»); упаковка — в том же порядке, строка сопоставляется одним правилом; ничьей между правилами нет. Поле порядка не нужно. Алгоритм — `05-domain-rules.md` §5 | +| OQ-174 | Какая версия правил элиминации (§4) применяется к версии консолидации, если `consolidation_version.elimination_rules_version` не задан: открытые на сегодня, действующие на отчётную дату консолидации или на дату её составления; когда фиксировать номер версии | ревью arm-core PR #141 (21.10.2026) | §4, §5, AURORA-1536 | **закрыт решением владельца 21.10.2026 (docs #145):** версия правил, действующая на дату составления консолидации (создания версии), а не на отчётный период; фиксируется в `elimination_rules_version` при создании версии или первом расчёте, не в GET-запросе; реализация — AURORA-1536; до неё расчёты берут открытые правила (`valid_to IS NULL`, сейчас одна версия v1) | diff --git a/dev/frontend-api-guide.md b/dev/frontend-api-guide.md index cf340b1..06a241c 100644 --- a/dev/frontend-api-guide.md +++ b/dev/frontend-api-guide.md @@ -558,6 +558,28 @@ line_code_text}` — строки `unreadable` / `missing`, у которых в «Ответственный» на [34] — `lock.locked_by_name`, иначе `initiator.name`; «Утверждён в РФ» / «Верифицирован в ГО» — «—». 13. **`warnings` строк** — диагностика, не контракт: показывать как подсказку. +### 5.7.1 Шахматка и результирующая таблица ВГО (Срез 5, правила — `05-domain-rules.md` §6) + +Префикс — `/consolidations/versions/{version_id}`. Права — `CONSOLIDATION_VIEW` и policy версии (чужая — 404); блокировка +версии не нужна. Расчёт — на лету по сводной ОСВ версии, ничего не хранится. + +| Метод и путь | Запрос | Ответ | Ошибки | +|---|---|---|---| +| `GET /directories/accounts` (`DIRECTORY_VIEW`) | — | `AccountOut[] {id, code, parent_id?, name, kind?, row_type, is_off_balance, is_debit, is_credit}` — план счетов целиком, деревья Дт/Кт строятся по `parent_id` | — | +| `GET …/elimination-rules` | — | `{version_no?, is_version_fixed, rules[] {id, rule_no, version_no, statement_type, side_1, measure, company_1 {accounts[], excluded[]}, company_2 {…}}}` — правила, по которым строятся пресеты; без зафиксированной версии — открытые правила с максимальным `version_no` | 404 | +| `GET …/intercompany-matrix/all` | — | `IntercompanyMatrixOut` по всем счетам | 404 | +| `POST …/intercompany-matrix/manual` | `{debit_account_ids[], credit_account_ids[]}` (обе стороны непустые) | `IntercompanyMatrixOut` | 404; 422 `ACCOUNTS_REQUIRED`, массив валидации | +| `GET …/intercompany-matrix/preset/{rule_id}` | — | `IntercompanyMatrixOut` по счетам сторон правила (с исключениями), показатель — `measure` правила | 404 (правило не найдено или не действует для версии); 422 `INVALID_RULE` (не ББ, неверная сторона/показатель), `ACCOUNTS_REQUIRED` | +| `GET …/intercompany-matrix/all/export`, `POST …/manual/export`, `GET …/preset/{rule_id}/export` | как у расчёта | xlsx; имя — из `Content-Disposition` | как у расчёта | +| `GET …/intercompany-matrix/result-table` | — | `{companies[] {id, name}, articles[] {code, name, amounts[] {company_id, amount}, group_total}}` — пять статей §6 | 404; 422 `RESULT_ACCOUNTS_MISSING` (в плане счетов нет счёта статьи, коды в тексте) | +| `GET …/intercompany-matrix/result-table/export` | — | xlsx | как у расчёта | + +`IntercompanyMatrixOut` — `{companies[] {id, name}, cells[] {company_a_id, company_b_id, amount_a, amount_b, variance_amount, +variance_percent?, exceeds_threshold, one_sided, skipped_osv_entry_count, osv_entry_ids_debit[], osv_entry_ids_credit[]}}`. +Порядок компаний задаёт обе оси; диагонали и пар без строк ОСВ в `cells` нет — показывать «—». Суммы — строки в рублях; +`variance_amount` — модуль разности, подсветка — по `exceeds_threshold` (> 5 % к меньшей сумме). `skipped_osv_entry_count` — +строки ОСВ пары без сопоставленного счёта, в суммы они не вошли. Выгрузки пишут в журнал `EXPORT`. + ### 5.8 Схемы ответов (кратко) Поля с `?` могут быть `null`, но ключ присутствует всегда. Полные схемы — `/openapi.json` и контракты по областям. @@ -742,8 +764,8 @@ async function download(path: string, fallbackName: string): Promise { 5. **Статус формы после правки** может стать `RECOGNIZED`, даже если у файла были предупреждения маппинга (arm-core#40, R-2) — ориентируйтесь на проверки и предупреждения, а не только на статус. 6. **Комментарии и правки нельзя удалить/отменить**; подтверждение необратимо. -7. **Нет в API** (показывать «—» или не показывать): маршрут согласования после `DATA_CORRECTION` (Срез 7), шахматка и ВГО - (Срез 5), КФО и ЕХ (Срезы 6–7), «Добавить версию», гудвилл, журнал аудита, шапка формы ОКЕИ/ОПФ/форма собственности/аудит +7. **Нет в API** (показывать «—» или не показывать): маршрут согласования после `DATA_CORRECTION` (Срез 7), сопоставление пар ВГО + и элиминация (AURORA-1536), КФО и ЕХ (Срезы 6–7), «Добавить версию», гудвилл, журнал аудита, шапка формы ОКЕИ/ОПФ/форма собственности/аудит (П-4). 8. **В проде нет `/openapi.json`** — генерируйте типы со стенда разработки. 9. **`Content-Disposition` не читается кросс-доменно** (нет `Access-Control-Expose-Headers` в CORS ядра): при фронте на