arm-core/api/src/domain/version_period.py
Andrey Epifancev a6418ca475 fix(consolidation): режим «период из версии» подменяет период только у ОСВ «не того» периода (#103)
Квартальные ОСВ, загруженные в консолидацию своего периода и уже привязанные, в режиме
становились «нарастающими за квартал версии»: select_sources возвращал все такие документы,
и свод брал их строки как есть — консолидация РБ 2024 Q3 на стенде задвоилась бы.
Теперь подмена — только если период шапки версии не подходит (fits_by_header);
регрессионный тест test_mode_keeps_header_period_when_it_fits_version.

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

95 lines
4.7 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.

"""ВРЕМЕННЫЙ режим «период ОСВ из версии консолидации» (arm-core#103, настройка `CONSOLIDATION_PERIOD_FROM_VERSION`).
Для тестов на произвольных ОСВ: документ ОСВ, загруженный в консолидацию (`stored_file.consolidation_id`), период шапки
которого версии НЕ подходит, считается нарастающим за год и квартал этой консолидации. Документ, подходящий версии по
шапке, остаётся как есть — квартальные ОСВ по-прежнему склеиваются, уже привязанные не задваиваются. Первичка не
мутируется: подменяется только представление документа (`VersionPeriodDocument`) при привязке к версии (`fits`, ключ
замены R-1), сборке свода (`select_sources`), чек-листе и колонке «ОСВ» периметра; карточка документа показывает период
из шапки.
Следствие: подменённые ОСВ одного счёта одного ЮЛ занимают один слот привязки (нарастающий за квартал версии), побеждает
подтверждённая последней, и склейки кварталов у них нет. ББ/ОФР и файлы без консолидации (рабочий стол) режим не
затрагивает.
ASSUMPTION(OQ-161): правила в `05-domain-rules.md` нет — режим временный, по решению владельца 12.10.2026; по умолчанию
выключен, без настройки поведение §2 / D-5 Среза 4 не меняется.
"""
import datetime
import uuid
from dataclasses import dataclass
from typing import Protocol
from src.models.enums import DocumentStatus, DocumentType, PeriodQuarter
class DocumentFields(Protocol):
"""Поля документа, которые читают привязка, свод и чек-лист (структурный тип: `Document` подходит)."""
@property
def id(self) -> uuid.UUID: ...
@property
def legal_entity_id(self) -> uuid.UUID: ...
@property
def document_type(self) -> DocumentType: ...
@property
def osv_account_code(self) -> str | None: ...
@property
def period_year(self) -> int | None: ...
@property
def period_quarter(self) -> PeriodQuarter | None: ...
@property
def is_cumulative(self) -> bool | None: ...
@property
def status(self) -> DocumentStatus: ...
@property
def confirmed_at(self) -> datetime.datetime | None: ...
@dataclass(frozen=True)
class VersionPeriodDocument:
"""Документ ОСВ с периодом версии: поля документа как есть, период — год и квартал консолидации, нарастающий."""
id: uuid.UUID
legal_entity_id: uuid.UUID
document_type: DocumentType
osv_account_code: str | None
period_year: int
period_quarter: PeriodQuarter
is_cumulative: bool
status: DocumentStatus
confirmed_at: datetime.datetime | None
def takes_version_period(
*,
enabled: bool,
document_type: DocumentType,
file_consolidation_id: uuid.UUID | None,
consolidation_id: uuid.UUID,
fits_by_header: bool,
) -> bool:
"""Берёт ли документ период версии: режим включён, документ — ОСВ, его файл загружен в эту консолидацию, а период
шапки версии не подходит (`fits_by_header` — период шапки подходит версии, как в `fits` без проверки периметра)."""
return (
enabled
and document_type == DocumentType.OSV
and file_consolidation_id == consolidation_id
and not fits_by_header
)
def with_version_period(document: DocumentFields, *, year: int, quarter: PeriodQuarter) -> VersionPeriodDocument:
"""Представление `document` как нарастающего за `year`/`quarter` версии; сам документ не меняется."""
return VersionPeriodDocument(
id=document.id,
legal_entity_id=document.legal_entity_id,
document_type=document.document_type,
osv_account_code=document.osv_account_code,
period_year=year,
period_quarter=quarter,
is_cumulative=True,
status=document.status,
confirmed_at=document.confirmed_at,
)