76 lines
3.8 KiB
Python
76 lines
3.8 KiB
Python
"""Автоподтверждение чистых документов при маппинге результата (osv-result-mapping «Автоподтверждение чистого
|
||
документа»; `05-domain-rules.md` §9.3, §9.5; OQ-157; design D-1–D-3 change `auto-confirm-clean-documents`).
|
||
|
||
Документ, получивший при маппинге `RECOGNIZED` (ТЗ 03_9 п. 4: «при отсутствии замечаний — „Загружен“»), становится
|
||
`CONFIRMED` от имени системы: `confirmed_by = NULL`, у формы `reviewed_by = NULL`, `audit_event(DOCUMENT_CONFIRM)` без
|
||
пользователя. Привязка к версиям и переход версии — тот же хук, что у ручного подтверждения, с автором
|
||
`stored_file.uploaded_by`. Вызывается в транзакции маппинга под заданием, файлом и документами (порядок блокировок D-5).
|
||
"""
|
||
|
||
import datetime
|
||
from collections.abc import Sequence
|
||
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from src.models.enums import AuditAction, AuditSection, DocumentStatus
|
||
from src.models.files import Document, StoredFile
|
||
from src.repositories import statements as statements_repo
|
||
from src.services import consolidation_documents
|
||
from src.services.audit import AuditService
|
||
from src.services.statements import FORM_TYPES, form_confirmable
|
||
|
||
AUTO_CONFIRM_DESCRIPTION = "автоподтверждение: без замечаний"
|
||
OBJECT_TYPE = "document"
|
||
|
||
|
||
def transition_comment(document: Document) -> str:
|
||
"""Комментарий перехода версии: «автоподтверждение документа <тип> [<счёт>]» (design решение №6)."""
|
||
parts = ["автоподтверждение документа", document.document_type.value]
|
||
if document.osv_account_code:
|
||
parts.append(document.osv_account_code)
|
||
return " ".join(parts)
|
||
|
||
|
||
async def auto_confirm(
|
||
session: AsyncSession, *, file: StoredFile, documents: Sequence[Document], now: datetime.datetime
|
||
) -> list[Document]:
|
||
"""Подтверждает документы `RECOGNIZED` файла (форма — только при `form_confirmable`, D-3); `NEEDS_CHECK` и прочие
|
||
не трогает. Возвращает подтверждённые документы по возрастанию `id`."""
|
||
audit = AuditService(session)
|
||
confirmed: list[Document] = []
|
||
for document in sorted(documents, key=lambda item: item.id):
|
||
if document.status is not DocumentStatus.RECOGNIZED:
|
||
continue
|
||
if not await form_confirmable(session, document):
|
||
continue
|
||
document.status = DocumentStatus.CONFIRMED
|
||
document.confirmed_by = None
|
||
document.confirmed_at = now
|
||
document.updated_at = now
|
||
if document.document_type in FORM_TYPES:
|
||
meta = await statements_repo.get_meta(session, document.id)
|
||
if meta is not None:
|
||
meta.reviewed_by = None
|
||
meta.reviewed_at = now
|
||
await session.flush()
|
||
await consolidation_documents.on_document_confirmed(
|
||
session,
|
||
audit,
|
||
document=document,
|
||
changed_by=file.uploaded_by,
|
||
comment=transition_comment(document),
|
||
now=now,
|
||
)
|
||
await audit.record(
|
||
action=AuditAction.DOCUMENT_CONFIRM,
|
||
section=AuditSection.PRIMARY_DOCUMENTS,
|
||
object_type=OBJECT_TYPE,
|
||
object_id=document.id,
|
||
user_id=None,
|
||
description=AUTO_CONFIRM_DESCRIPTION,
|
||
before_value={"status": DocumentStatus.RECOGNIZED.value},
|
||
after_value={"status": DocumentStatus.CONFIRMED.value},
|
||
)
|
||
confirmed.append(document)
|
||
return confirmed
|