"""Контракт v1.2: новые необязательные поля и значение DISCLOSURE (docs change slice-2b design D-1).""" import datetime from decimal import Decimal from src.contract.common import CONTRACT_VERSION from src.contract.result import ( FailedRelation, OsvHeader, StatementChecks, StatementDocument, StatementHeader, ) def test_contract_version_is_1_2() -> None: assert CONTRACT_VERSION == "1.2" def test_statement_document_accepts_disclosure_and_checks() -> None: document = StatementDocument( document_type="DISCLOSURE", locator="sheet:Пояснения", header=StatementHeader(form_name="Пояснения"), columns=[], lines=[], ) assert document.checks is None checked = StatementDocument.model_validate( { "document_type": "BALANCE", "locator": "sheet:ББ", "header": {}, "columns": [], "lines": [], "checks": { "relations_failed": [ { "column_index": 0, "relation": "1600 = 1100 + 1200", "expected": "10.00", "actual": "9.00", } ], "soft_relations_failed": [], "duplicate_line_codes": ["1110"], }, } ) assert checked.checks == StatementChecks( relations_failed=[ FailedRelation( column_index=0, relation="1600 = 1100 + 1200", expected=Decimal("10.00"), actual=Decimal("9.00"), ) ], soft_relations_failed=[], duplicate_line_codes=["1110"], ) wire = checked.model_dump(mode="json", by_alias=True, exclude_none=True) assert wire["checks"]["relations_failed"][0]["expected"] == "10.00" def test_osv_header_period_bounds_are_optional_dates() -> None: header = OsvHeader( organization_name="ООО", account_code_raw="60", period_text="1 квартал 2025 г.", ) assert header.period_start is None and header.is_from_year_start is None filled = OsvHeader.model_validate( { "organization_name": "ООО", "account_code_raw": "60", "period_text": "x", "period_start": "2024-10-01", "period_end": "2025-09-30", "is_from_year_start": False, } ) assert filled.period_start == datetime.date(2024, 10, 1) assert filled.period_end == datetime.date(2025, 9, 30)