"""Агрегат формы по коду (спека `arm-core` v5.19; Review Focus 2).""" import uuid from dataclasses import dataclass from decimal import Decimal from src.domain.statement_aggregate import AggLine, aggregate_by_code, checks_input from src.models.enums import StatementLineStatus C1 = uuid.UUID(int=1) C2 = uuid.UUID(int=2) L1, L5 = uuid.UUID(int=101), uuid.UUID(int=105) def line( # noqa: PLR0913 - поля строки теста status: str, code: str | None, *, r: int | None, c1: str | None = None, c2: str | None = None, id_: uuid.UUID | None = None, ) -> AggLine: amounts = {C1: Decimal(c1) if c1 is not None else None, C2: Decimal(c2) if c2 is not None else None} return AggLine(id_ or uuid.uuid4(), r, StatementLineStatus(status), code, amounts) def ok(code: str, *, r: int | None, c1: str | None = None, c2: str | None = None, id_: uuid.UUID | None = None): return line("ok", code, r=r, c1=c1, c2=c2, id_=id_) def test_repeated_code_sums() -> None: agg = aggregate_by_code([ok("2410", r=1, c1="100", id_=L1), ok("2410", r=5, c1="649", id_=L5)]) assert agg["2410"].amounts[C1] == Decimal("749") and agg["2410"].line_ids == (L1, L5) def test_empty_amounts_stay_null() -> None: assert aggregate_by_code([ok("1110", r=0), ok("1110", r=3)])["1110"].amounts[C1] is None assert aggregate_by_code([ok("1110", r=0), ok("1110", r=3, c1="5")])["1110"].amounts[C1] == Decimal("5") def test_non_ok_lines_excluded() -> None: agg = aggregate_by_code( [ line("detail", None, r=2, c1="7"), line("unreadable", None, r=3, c1="9"), line("missing", None, r=4, c1="1"), ok("1250", r=5, c1="3"), ] ) assert list(agg) == ["1250"] def test_template_line_counts_as_ok() -> None: agg = aggregate_by_code([ok("1250", r=None, c1="10")]) assert agg["1250"].amounts[C1] == Decimal("10") and agg["1250"].has_source_line is False def test_codes_ascending_and_template_line_ids_last() -> None: agg = aggregate_by_code([ok("2400", r=None, id_=L5), ok("1600", r=2), ok("2400", r=7, id_=L1)]) assert list(agg) == ["1600", "2400"] and agg["2400"].line_ids == (L1, L5) assert agg["2400"].has_source_line is True def test_reference_name_from_callback() -> None: agg = aggregate_by_code([ok("1250", r=1)], reference_name=lambda code: f"имя {code}") assert agg["1250"].reference_name == "имя 1250" @dataclass class Col: id: uuid.UUID column_index: int def test_checks_input_skips_empty_template_codes() -> None: agg = aggregate_by_code( [ok("1250", r=None), ok("1260", r=None, c1="4"), ok("1270", r=3), ok("1280", r=4, c1="1"), ok("1280", r=None)] ) indexes, lines = checks_input([Col(C2, 1), Col(C1, 0)], agg) assert indexes == [0, 1] assert [code for code, _ in lines] == ["1260", "1270", "1280"] assert dict(lines)["1260"] == {0: Decimal("4"), 1: None}