"""Адаптация готовых позиций VGO в агрегат таблицы корректировок.""" import uuid from decimal import Decimal from types import SimpleNamespace from src.schemas.consolidations import ( EliminationMatchedPairOut, VgoAssignmentGroupOut, VgoAssignmentPositionOut, VgoUnallocatedPositionOut, ) from src.services.correction_source import VgoCorrectionSource, _RuleSpec def test_vgo_positions_form_oriented_company_aggregate() -> None: first_id, second_id, rule_id = (uuid.uuid4() for _ in range(3)) rule = SimpleNamespace( id=rule_id, rule_no=6, article_1_line="1230", article_2_line="1520", side_1="D", measure="closing", elimination_mode="min", ) group = VgoAssignmentGroupOut( rule_id=rule_id, rule_no=6, article_1_line="1230", article_2_line="1520", measure="closing", company_a_id=first_id, company_a_name="Компания А", company_b_id=second_id, company_b_name="Компания Б", amount_a=Decimal("100"), amount_b=Decimal("95"), deviation_amount=Decimal("5"), deviation_percent=Decimal("5.26"), with_discrepancy=[ EliminationMatchedPairOut( rule_id=rule_id, company_a_id=first_id, company_b_id=second_id, amount_a=Decimal("100"), amount_b=Decimal("95"), deviation_amount=Decimal("5"), deviation_percent=Decimal("5.26"), osv_entry_ids_a=[uuid.UUID(int=1)], osv_entry_ids_b=[uuid.UUID(int=2)], ) ], positions=[ VgoAssignmentPositionOut( entry_ids=[uuid.UUID(int=1)], legal_entity_id=first_id, counterparty_id=second_id, account_code="62.01", side="D", amount=Decimal("100"), candidate_rule_ids=[uuid.UUID(int=7)], ), VgoAssignmentPositionOut( entry_ids=[uuid.UUID(int=2)], legal_entity_id=second_id, counterparty_id=first_id, account_code="60.01", side="K", amount=Decimal("95"), action="ASSIGN", ), ], ) aggregate = VgoCorrectionSource._aggregate(group, _RuleSpec(rule)) # type: ignore[arg-type] assert (aggregate.company_1.id, aggregate.company_2.id) == (first_id, second_id) assert aggregate.side_1.amount == Decimal("100.00") assert aggregate.side_2.amount == Decimal("95.00") assert aggregate.deviation_percent == Decimal("5") / Decimal("95") * 100 assert aggregate.exceeds_threshold assert aggregate.side_1.entries[0].entry_ids == [uuid.UUID(int=1)] assert aggregate.side_1.entries[0].decision == "AUTO" assert aggregate.side_1.entries[0].candidate_rule_ids == [uuid.UUID(int=7)] assert aggregate.side_2.entries[0].decision == "ASSIGN" assert aggregate.pairs[0].side_1.entries[0].entry_ids == [uuid.UUID(int=1)] assert aggregate.pairs[0].side_2.entries[0].entry_ids == [uuid.UUID(int=2)] def test_unallocated_position_forms_correction_contract() -> None: owner_id, counterparty_id, first_rule_id, second_rule_id = (uuid.uuid4() for _ in range(4)) first = SimpleNamespace( id=first_rule_id, side_1="D", article_1_line="1230", article_2_line="1520", ) second = SimpleNamespace( id=second_rule_id, side_1="D", article_1_line="1230", article_2_line="1510", ) position = VgoUnallocatedPositionOut( entry_ids=[uuid.UUID(int=9)], legal_entity_id=owner_id, legal_entity_name="Компания А", counterparty_id=counterparty_id, counterparty_name="Компания Б", account_code="76.05", side="D", amount=Decimal("142878"), candidate_rule_ids=[first_rule_id, second_rule_id], reason="MULTIPLE_RULES", excluded=False, ) result = VgoCorrectionSource._unallocated( position, {first_rule_id: _RuleSpec(first), second_rule_id: _RuleSpec(second)}, # type: ignore[arg-type] ) assert result.owner.id == owner_id assert result.counterparty.id == counterparty_id assert result.line_code == "1230" assert result.candidate_rule_ids == [first_rule_id, second_rule_id] assert result.reason == "MULTIPLE_RULES"