Andrey Epifancev c1288d08fb fix(normalizer): итоги финального ревью — Money, статус при ошибочном файле, пропущенные строки, длина дат, дубли yaml
- C-1 (№30): сумма с более чем двумя знаками после запятой не принимается (amount=null, string_value, is_recognized=false);
  confidence ячеек и шапки приводится к [0, 100], NaN и бесконечность дают 0
- F-A (№28): ошибочный файл набора при успешном понижает статус до needs_check
- F-B: «ИНН не распознан» только когда ИНН не извлечён, иначе «ИНН распознан неуверенно»
- №29: предупреждения «строк с нечисловым кодом пропущено: N» и «строк без кода с суммами пропущено: N»
- I-3 (№31): тексты дат длиннее 200 символов не разбираются и не проходят fix_lookalikes
- T1.3 (№33): загрузчик yaml отклоняет повторяющиеся ключи; тавтологичный тест дублей заменён настоящим
- гигиена: докстринг amounts.py описывает фактическое поведение (все точки удаляются), мёртвые noqa в ocr/__init__.py

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012vJkmBGKKqMoEMzvsXG3y2
2026-10-07 03:35:10 +04:00

49 lines
2.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Суммы из OCR-ячеек (§11.1 п. 7): перенос `_parse_amount`/`_is_blank` старого ядра."""
from decimal import Decimal
import pytest
from src.normalizer.ocr.amounts import ParsedAmount, is_blank, parse_amount
@pytest.mark.parametrize(
("raw", "amount", "verified"),
[
("13 070", Decimal("13070"), True),
("(6032409)", Decimal("-6032409"), True),
("(7744536}", Decimal("7744536"), False), # закрывающая скобка не распознана: минус не ставится (решение №12)
("1 234,56", Decimal("1234.56"), True),
("1.234.567", Decimal("1234567"), False), # несколько точек — разделители тысяч; текст изменён → не verified
("30127", Decimal("30127"), True),
("211(1 |", Decimal("2111"), False),
("не ****", None, False),
("", None, True),
("--", None, True), # прочерк: ничего не отброшено, суммы нет (NULL)
(":", None, False),
# несколько точек: удаляются ВСЕ точки, десятичная часть теряется (`1.234,56` — не 1234.56), всегда не verified
("1.234,56", Decimal("123456"), False),
("1,234.56", Decimal("123456"), False),
(
"1,234",
Decimal("1.234"),
True,
), # знаков после запятой больше двух — `Money` отсекает `document._value` (№30)
# №13: скобки без содержимого — не сумма, но и не «неразобранный текст»
("()", None, True),
("( )", None, True),
("(.)", None, True),
("(+5)", Decimal("-5"), True), # в скобках знак заменяется минусом
],
)
def test_parse_amount(raw: str, amount: Decimal | None, verified: bool) -> None:
assert parse_amount(raw) == ParsedAmount(amount, verified)
@pytest.mark.parametrize(
("raw", "expected"),
[("", True), ("-", True), ("—", True), (" – ", True), ("0", False), ("x", False)],
)
def test_is_blank(raw: str, expected: bool) -> None:
assert is_blank(raw) is expected