Ajustes conforme relatorio de testes 2026-08-27
This commit is contained in:
55
app/domain/contas/line_reference.py
Normal file
55
app/domain/contas/line_reference.py
Normal file
@@ -0,0 +1,55 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unicodedata
|
||||
from typing import Any
|
||||
|
||||
_DIGIT_WORDS = {
|
||||
"zero": "0", "um": "1", "uma": "1", "dois": "2", "duas": "2",
|
||||
"tres": "3", "quatro": "4", "cinco": "5", "seis": "6", "sete": "7",
|
||||
"oito": "8", "nove": "9",
|
||||
}
|
||||
|
||||
|
||||
def _norm(text: Any) -> str:
|
||||
value = unicodedata.normalize("NFKD", str(text or "").casefold())
|
||||
value = "".join(ch for ch in value if not unicodedata.combining(ch))
|
||||
return re.sub(r"\s+", " ", value).strip()
|
||||
|
||||
|
||||
def extract_requested_line_reference(text: Any) -> dict[str, str] | None:
|
||||
"""Extrai somente uma referência explícita de linha citada pelo usuário.
|
||||
|
||||
Não transforma a referência em identidade autorizada. Essa decisão pertence à
|
||||
política de linha ativa no domínio Contas.
|
||||
"""
|
||||
raw = str(text or "").strip()
|
||||
if not raw:
|
||||
return None
|
||||
norm = _norm(raw)
|
||||
|
||||
# Número completo explicitamente presente no texto (10 a 13 dígitos, com
|
||||
# separadores opcionais). Evita capturar valores monetários ou protocolos curtos.
|
||||
for match in re.finditer(r"(?<!\d)(?:\+?\d[\s().-]*){10,13}(?!\d)", raw):
|
||||
digits = "".join(ch for ch in match.group(0) if ch.isdigit())
|
||||
if 10 <= len(digits) <= 13:
|
||||
return {"kind": "full", "value": digits, "raw": match.group(0).strip()}
|
||||
|
||||
# Referência por final da linha: "final 4321", "final quatro três dois um",
|
||||
# "termina em 4321". Só a referência é extraída; nunca é assumida como MSISDN.
|
||||
marker = re.search(r"\b(?:final|termina(?:ndo)?\s+em|terminado\s+em)\b(.{0,45})", norm)
|
||||
if marker:
|
||||
tail = marker.group(1)
|
||||
numeric = re.search(r"\b(\d{4})\b", tail)
|
||||
if numeric:
|
||||
return {"kind": "suffix", "value": numeric.group(1), "raw": numeric.group(1)}
|
||||
tokens = re.findall(r"[a-z]+", tail)
|
||||
digits: list[str] = []
|
||||
for token in tokens:
|
||||
if token in _DIGIT_WORDS:
|
||||
digits.append(_DIGIT_WORDS[token])
|
||||
if len(digits) == 4:
|
||||
return {"kind": "suffix", "value": "".join(digits), "raw": " ".join(tokens[:4])}
|
||||
elif digits:
|
||||
break
|
||||
return None
|
||||
Reference in New Issue
Block a user