arm-core/api/src/services/elimination_rules.py
Andrey Epifancev b4522addc0 feat: DBML v5.23 — версия правил обязательна; список пар ВГО версии (ревью #175, AURORA-1536)
- consolidation_version.elimination_rules_version NOT NULL: миграция 0010
  проставляет существующим версиям номер правил, действовавших на дату
  создания (по Москве), иначе последних открытых; без правил — отказ;
  создание версии без действующих правил — 409 ELIMINATION_RULES_MISSING;
  ветки «правила не зафиксированы» убраны (rules, preset, is_version_fixed
  всегда true);
- GET …/elimination-totals: все тройки «правило ББ × упорядоченная пара
  периметра» с ΣA, ΣB, расхождением, суммой элиминации, статусом
  AUTO/DISCREPANCY/ONE_SIDED/MANUAL и osv_entry_ids; сводная ОСВ строится
  один раз; сбор строк сторон вынесен в _collect_rule_sides — общий
  с упаковкой тройки.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 18:42:10 +04:00

60 lines
2.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Чтение правил элиминации для версии консолидации."""
import uuid
from sqlalchemy.ext.asyncio import AsyncSession
from src.common.exceptions import NotFoundError
from src.domain.policy import VisibilityScope
from src.repositories import consolidations as consolidations_repo
from src.repositories import elimination_rules as rules_repo
from src.schemas.consolidations import EliminationRuleOut, EliminationRulesOut, IntercompanyMatrixRuleSideOut
VERSION_NOT_FOUND = "версия консолидации не найдена"
class EliminationRuleService:
"""Правила выбранной версии из БД с учетом видимости консолидации."""
def __init__(self, session: AsyncSession, scope: VisibilityScope) -> None:
self._session = session
self._scope = scope
async def list_rules(self, consolidation_version_id: uuid.UUID) -> EliminationRulesOut:
"""Правила §4 версии консолидации с проверкой видимости и основанием выбора."""
found = await consolidations_repo.get_version(self._session, self._scope, consolidation_version_id)
if found is None:
raise NotFoundError(VERSION_NOT_FOUND)
version, _ = found
# с v5.23 версия правил фиксируется при создании версии консолидации и не бывает пустой
version_no = version.elimination_rules_version
rows = await rules_repo.list_rules_with_accounts(self._session, version_no)
by_id: dict[uuid.UUID, EliminationRuleOut] = {}
for rule, account in rows:
result = by_id.get(rule.id)
if result is None:
result = EliminationRuleOut.model_validate(
{
"id": rule.id,
"rule_no": rule.rule_no,
"version_no": rule.version_no,
"statement_type": rule.statement_type,
"side_1": rule.side_1,
"measure": rule.measure,
"company_1": IntercompanyMatrixRuleSideOut(accounts=[], excluded=[]),
"company_2": IntercompanyMatrixRuleSideOut(accounts=[], excluded=[]),
}
)
by_id[rule.id] = result
if account is None:
continue
side = result.company_1 if account.company_no == 1 else result.company_2
(side.excluded if account.is_excluded else side.accounts).append(account.account_id)
return EliminationRulesOut(
version_no=version_no,
is_version_fixed=True,
rules=list(by_id.values()),
)