Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W
118 lines
4.3 KiB
Python
118 lines
4.3 KiB
Python
from dataclasses import replace
|
||
from datetime import date
|
||
from decimal import Decimal as D
|
||
|
||
from arm_statements.header import parse_header
|
||
from arm_statements.issues import make_warning
|
||
from arm_statements.loader import Rules
|
||
from arm_statements.model import (
|
||
DocStatus,
|
||
DocumentType,
|
||
EnvelopeStatus,
|
||
FormVariant,
|
||
LineStatus,
|
||
PeriodKind,
|
||
Severity,
|
||
StatementChecks,
|
||
StatementColumn,
|
||
StatementDocument,
|
||
StatementLine,
|
||
StatementValue,
|
||
)
|
||
from arm_statements.status import (
|
||
StatusInput,
|
||
StatusLine,
|
||
StatusValue,
|
||
document_status,
|
||
envelope_status,
|
||
status_input,
|
||
)
|
||
from arm_statements.tests.builders import hdr
|
||
|
||
OK, DETAIL, UNREADABLE = LineStatus.OK, LineStatus.DETAIL, LineStatus.UNREADABLE
|
||
DONE, CHECK = DocStatus.DONE, DocStatus.NEEDS_CHECK
|
||
BASE = StatusInput(
|
||
document_type=DocumentType.BALANCE,
|
||
layout_found=True,
|
||
has_organization_or_inn=True,
|
||
period_known=True,
|
||
needs_review_fields=(),
|
||
lines=(StatusLine(OK, False),),
|
||
values=(StatusValue(OK, False),),
|
||
hard_failures=0,
|
||
accepted=False,
|
||
warning_severities=(Severity.INFO,),
|
||
)
|
||
|
||
|
||
def test_clean_form_done() -> None:
|
||
assert document_status(BASE) is DONE
|
||
|
||
|
||
def test_unreadable_line_blocks() -> None:
|
||
assert document_status(replace(BASE, lines=(StatusLine(OK, False), StatusLine(UNREADABLE, False)))) is CHECK
|
||
|
||
|
||
def test_detail_value_does_not_block() -> None:
|
||
lines = (StatusLine(OK, False), StatusLine(DETAIL, False))
|
||
values = (StatusValue(OK, False), StatusValue(DETAIL, True))
|
||
assert document_status(replace(BASE, lines=lines, values=values)) is DONE
|
||
|
||
|
||
def test_blocking_conditions() -> None:
|
||
hard = 2
|
||
assert document_status(replace(BASE, values=(StatusValue(OK, True),))) is CHECK
|
||
assert document_status(replace(BASE, lines=(StatusLine(OK, True),))) is CHECK
|
||
assert document_status(replace(BASE, needs_review_fields=("report_date",))) is CHECK
|
||
assert document_status(replace(BASE, hard_failures=hard)) is CHECK
|
||
assert document_status(replace(BASE, hard_failures=hard, accepted=True)) is DONE
|
||
assert document_status(replace(BASE, warning_severities=(Severity.ERROR,))) is CHECK
|
||
assert document_status(replace(BASE, layout_found=False)) is CHECK
|
||
assert document_status(replace(BASE, has_organization_or_inn=False)) is CHECK
|
||
assert document_status(replace(BASE, period_known=False)) is CHECK
|
||
|
||
|
||
def test_disclosure_always_done() -> None:
|
||
disclosure = replace(BASE, document_type=DocumentType.DISCLOSURE, layout_found=False, lines=(), values=())
|
||
assert document_status(disclosure) is DONE
|
||
|
||
|
||
def test_envelope(rules: Rules) -> None:
|
||
assert envelope_status([DONE, CHECK], []) is EnvelopeStatus.NEEDS_CHECK
|
||
assert envelope_status([DONE], []) is EnvelopeStatus.DONE
|
||
lost = make_warning("TABLE_LOST", "таблица без колонки кодов", rules, locator="file:a.json;table:1")
|
||
assert envelope_status([DONE], [lost]) is EnvelopeStatus.NEEDS_CHECK
|
||
assert envelope_status([], []) is EnvelopeStatus.ERROR
|
||
|
||
|
||
def test_status_input_from_document(rules: Rules) -> None:
|
||
head = parse_header(hdr(organization_name="ООО «Пример»", units="тыс. руб."), rules)
|
||
column = StatementColumn(2, "На 30.09.2025", 100.0, date(2025, 9, 30), PeriodKind.ABSOLUTE)
|
||
value = StatementValue(2, D("5"), None, "5", 60.0, True, needs_review=True)
|
||
detail = StatementLine(1, "row:1", DETAIL, None, None, None, "в т. ч.", 100.0, "row:0", False, (value,))
|
||
line = StatementLine(
|
||
0, "row:0", OK, "1210", "1210", 100.0, "Запасы", 100.0, None, False, (replace(value, needs_review=False),)
|
||
)
|
||
doc = StatementDocument(
|
||
DocumentType.BALANCE,
|
||
FormVariant.FULL,
|
||
"file:t.json;table:0",
|
||
head,
|
||
(column,),
|
||
(line, detail),
|
||
StatementChecks((), ()),
|
||
DocStatus.DONE,
|
||
(),
|
||
)
|
||
data = status_input(doc)
|
||
assert (data.layout_found, data.has_organization_or_inn, data.period_known, data.hard_failures) == (
|
||
True,
|
||
True,
|
||
True,
|
||
0,
|
||
)
|
||
assert data.values == (StatusValue(OK, False), StatusValue(DETAIL, True))
|
||
assert document_status(data) is DONE
|
||
empty = replace(doc, columns=(), lines=(), checks=None)
|
||
assert (status_input(empty).layout_found, status_input(empty).period_known) == (False, False)
|