"""Шапка документа из полей `data_ocr` (§11.1 п. 8): ИНН — только цифры, единицы — очищенный текст, дата отчёта — `parse_date` после замены двойников; «распознано» — `confidence == 100` и сырой текст без мусора.""" from collections.abc import Mapping from dataclasses import dataclass from datetime import date from src.normalizer.ocr.dates import is_date_sized, parse_date from src.normalizer.ocr.text import clamp_confidence, clean_value, collapse_whitespace, digits_only, fix_lookalikes __all__ = ["FileHeader", "parse_file_header"] FULL_CONFIDENCE = 100.0 CAPPED_CONFIDENCE = 99.0 @dataclass(frozen=True) class FileHeader: organization_name: str | None organization_confidence: float | None inn: str | None inn_confidence: float | None units: str | None report_date_text: str | None report_date: date | None report_date_recognized: bool def _field(data_ocr: Mapping[str, object], name: str) -> tuple[str, float | None]: raw = data_ocr.get(name) if not isinstance(raw, Mapping): return "", None text = raw.get("form_name") text_str = str(text) if isinstance(text, str) else "" return (text_str, clamp_confidence(raw.get("confidence"))) def parse_file_header(data_ocr: Mapping[str, object], lookalikes: Mapping[str, str]) -> FileHeader: organization, organization_confidence = _field(data_ocr, "organization") inn_raw, inn_confidence = _field(data_ocr, "inn") units_raw, _ = _field(data_ocr, "units") date_raw, date_confidence = _field(data_ocr, "date") organization_name = collapse_whitespace(organization) or None inn = digits_only(inn_raw) or None if inn is None: inn_confidence = None elif inn_confidence is not None and inn_raw.strip() != inn: inn_confidence = min(inn_confidence, CAPPED_CONFIDENCE) # решение №31: длинный текст не разбирается и не проходит `fix_lookalikes` report_date = ( parse_date(fix_lookalikes(date_raw, lookalikes)) if date_raw.strip() and is_date_sized(date_raw) else None ) return FileHeader( organization_name=organization_name, organization_confidence=organization_confidence if organization_name is not None else None, inn=inn, inn_confidence=inn_confidence, units=clean_value(units_raw) or None, report_date_text=date_raw.strip() or None, report_date=report_date, report_date_recognized=date_confidence == FULL_CONFIDENCE and report_date is not None, )