From 598ac83855e877b2019976b7e005dae27dd4921a Mon Sep 17 00:00:00 2001 From: Andrey Epifancev Date: Sun, 18 Oct 2026 14:28:20 +0400 Subject: [PATCH] =?UTF-8?q?recompute=20=D0=B4=D0=BB=D1=8F=20DISCLOSURE:=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=BB=D0=BD=D1=8B=D0=B5=20=D1=81=D0=BB=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D1=80=D0=B8=20needs=5Freview=20=D0=B8=20=D1=80=D0=BE?= =?UTF-8?q?=D0=B4=D0=B8=D1=82=D0=B5=D0=BB=D0=B8=20detail=20(I-3)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01BJKMLHdxMwSUeYcdkwqX4W --- arm_statements/recompute.py | 7 +++--- arm_statements/tests/test_recompute.py | 31 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/arm_statements/recompute.py b/arm_statements/recompute.py index 8e2b335..887f276 100644 --- a/arm_statements/recompute.py +++ b/arm_statements/recompute.py @@ -127,13 +127,14 @@ def recompute(form: StoredForm, rules: Rules | None = None) -> RecomputeResult: """Шаги 6–8 по сохранённым данным: вариант, редакция, §7, `needs_review`, родители `detail`, статус.""" rules = rules if rules is not None else default_rules() if form.document_type is DocumentType.DISCLOSURE: + ordered = sorted(form.lines, key=_sort_key) return RecomputeResult( form_variant=None, edition=edition_by_date(form.effective_date), checks=StatementChecks((), ()), - line_needs_review={}, - value_needs_review={}, - detail_parents={}, + line_needs_review={line.key: False for line in ordered}, + value_needs_review={(line.key, v.column_key): False for line in ordered for v in line.values}, + detail_parents=_detail_parents(ordered), status=DocStatus.DONE, ) lines = sorted(form.lines, key=_sort_key) diff --git a/arm_statements/tests/test_recompute.py b/arm_statements/tests/test_recompute.py index 9564b8a..7e9d3c0 100644 --- a/arm_statements/tests/test_recompute.py +++ b/arm_statements/tests/test_recompute.py @@ -5,6 +5,7 @@ from decimal import Decimal as D from arm_statements import StoredColumn, StoredForm, StoredLine, StoredValue, choose_edition, recompute from arm_statements.loader import Rules from arm_statements.model import DocStatus, DocumentType, Edition, FormVariant, LineStatus, PeriodKind +from arm_statements.structure import edition_by_date OK, DETAIL = LineStatus.OK, LineStatus.DETAIL COL = StoredColumn("c1", 2, date(2025, 9, 30), PeriodKind.ABSOLUTE) @@ -85,3 +86,33 @@ def test_accepted_and_empty_edit_line(rules: Rules) -> None: broken = form(sl("a", 0, "1600", "100"), sl("b", 1, "1700", "90"), sl("e", None, "1220", None)) assert recompute(broken, rules).status is DocStatus.NEEDS_CHECK assert recompute(replace(broken, accepted=True), rules).status is DocStatus.DONE + + +def test_disclosure_has_complete_maps(rules: Rules) -> None: + """I-3: для расшифровки в словарях ключи всех строк и значений, а не пустые словари.""" + stored = form( + sl("a", 0, "1110", "10"), + sl("d", 1, None, "7", status=DETAIL), + sl("e", None, "1120", None), + document_type=DocumentType.DISCLOSURE, + ) + result = recompute(stored, rules) + assert result.line_needs_review == {"a": False, "d": False, "e": False} + assert result.value_needs_review == {("a", "c1"): False, ("d", "c1"): False, ("e", "c1"): False} + assert result.detail_parents == {"d": "a"} + assert (result.form_variant, result.checks.relations_failed, result.status) == (None, (), DocStatus.DONE) + assert result.edition is edition_by_date(date(2025, 9, 30)) + + +def test_edit_line_without_amount_is_excluded_from_checks_and_variant(rules: Rules) -> None: + """T18.6: пустая строка правки не участвует в §7 и не влияет на вариант.""" + base = [sl("a", 0, "1150", "50"), sl("b", 1, "1600", "50"), sl("c", 2, "1300", "50"), sl("d", 3, "1700", "50")] + with_edit = recompute(form(*base, sl("e", None, "1100", None)), rules) + without = recompute(form(*base), rules) + assert with_edit.form_variant is without.form_variant is FormVariant.SIMPLIFIED + assert with_edit.checks == without.checks + + +def test_detail_without_row_index_has_no_parent(rules: Rules) -> None: + stored = form(sl("a", 0, "1210", "10"), sl("d", None, None, "3", status=DETAIL)) + assert recompute(stored, rules).detail_parents == {"d": None}