Revalidação da leitura da operadora 5060 - Unimed.

This commit is contained in:
Gabriel 2026-09-28 08:24:01 -03:00
parent ce611ad9ca
commit 74c49e45c4
3 changed files with 32 additions and 2 deletions

View File

@ -387,3 +387,13 @@ Nada mudou no cálculo: `_aplica_teto_familia` nunca olhou o código da empresa
Na sequência o usuário confirmou que a **Amil Odonto (898) também vale pro grupo inteiro**, e a `amil_898_tecnomyl` recebeu a mesma tupla de quatro códigos. Vale notar que incluir um código aqui só DESTRAVA a possibilidade de cadastrar aquela regra pra aquela empresa — não aplica nada sozinho: uma empresa do grupo que não tenha o plano odontológico simplesmente nunca vai ter uma regra de custeio cadastrada pra Amil.
**Cuidado ao mexer**: incluir um código a mais nessa tupla aplica silenciosamente o teto de um cliente na folha de outro — só fazer com confirmação de que as condições são idênticas.
### Rodada 134 — Unimed Saúde (5060): coparticipação em PDF perdia beneficiários em silêncio
Na importação da empresa **1879 (MARV Empreendimentos)**, competência 09/2026, a coparticipação extraída somava R$ 1.697,28 contra R$ 2.102,94 impressos no relatório ("Total do Titulo"). Duas causas, as duas no parser (`operadoras/unimed/saude.py`):
1. A coluna "Mat/Orig", entre o grau de dependência e o CPF, vem preenchida em algumas linhas (ex.: "AMANDA DESTROTITULAR 241 067.678.609-05"). `_PESSOA_COPARTICIPACAO_RE` não aceitava nada entre grau e CPF, então a linha da pessoa não casava. Quando era a primeira pessoa da família, todos os itens dela eram descartados **sem ir pra auditoria** (AMANDA R$ 55,00 e JESSICA R$ 142,48). Corrigido tornando a coluna opcional.
2. Código de serviço "ANE" (anestesia) não reconhecido por `_ITEM_COPARTICIPACAO_RE`: R$ 208,18 faltando na MARIA LUCIENE. Acrescentado.
Validado contra o arquivo real: 6 beneficiários, R$ 2.102,94, batendo com o "Total do Titulo" e com cada "Total da Familia". A mensalidade da mesma competência não foi afetada (12 beneficiários, R$ 5.438,89). A importação id 97, em revisão, foi criada antes da correção e precisa ser refeita.

View File

@ -166,6 +166,7 @@ Até uma rodada anterior, "Arquivo da operadora" (passo 2 de "Nova Importação"
- **Validado contra os dois arquivos reais** (não só texto colado numa conversa — o texto que sai de um PDF colado no chat **não é** o que `pdfplumber.extract_text()` de fato produz, então não serve pra desenhar regex com confiança; só o arquivo real confirma). Bate exatamente com "Total da Familia"/"Total da Sequencia" impresso no próprio relatório (1.372,08 de coparticipação, 6.061,74 de mensalidade) e com o casamento por CPF contra a planilha padrão real da empresa — toda família presente na planilha bateu centavo a centavo; a família ausente da planilha de teste foi corretamente pra auditoria, não ignorada silenciosamente.
- **Bug real corrigido (competência 09/2026, empresa Questor 604)**: `_GRAUS_DEPENDENCIA` não previa "COMPANHEIRO"/"COMPANHEIRA" — a coluna "Grau Dep." tem largura fixa de 10 caracteres, então esse grau (11 caracteres) sai truncado no relatório real como "COMPANHEIR". Sem essa entrada, a linha desse dependente não casava com `_PESSOA_COPARTICIPACAO_RE`, e o item de serviço dele (que ainda batia em `_ITEM_COPARTICIPACAO_RE`) era somado por engano no `pessoa_atual` anterior — na prática, no titular da mesma família (primeiro caso real de família com coparticipação em titular **e** dependente ao mesmo tempo; até então só se via titular sozinho). Corrigido acrescentando "COMPANHEIRO"/"COMPANHEIRA"/"COMPANHEIR" (a forma truncada, a que de fato aparece) a `_GRAUS_DEPENDENCIA`; validado rodando `extrai()` de ponta a ponta contra o arquivo real (família R$144,35 → titular R$134,33 + dependente R$10,02, batendo com "Total da Familia" impresso, e total geral do arquivo R$606,61 batendo com a soma dos "Total da Familia" das 3 famílias do documento). A importação já existente no banco (id 88, competência 09/2026) tinha sido corrigida manualmente na tela de Revisão antes deste fix (`ImportacaoPlanoSaudeAlteracao` ids 29/30) — não precisou de correção retroativa, só as importações futuras dependiam deste ajuste no parser.
- **Bug real corrigido (empresa Questor 1970, "Rede Brasil de Mídia OOH", competência 08/2026)**: `_ITEM_COPARTICIPACAO_RE` exigia fronteira de palavra (`\b`) dos dois lados do código de "Tipo Serviço" (CON/EXA/HOS/CLI/ODO/MED). Neste arquivo real, esse código vem **colado sem espaço** ao final do nome do Prestador (ex.: "...MARCELO FABRICCON 10101012...", "...LUCIANO GUSTAVEXA 40316572..." — mesmo estilo de coluna colada já visto no "Beneficiario" da nota acima, só que aqui na coluna de tipo de serviço), então nenhuma linha de item deste arquivo casava — resultado final era **zero beneficiários** ("Nenhum beneficiário foi encontrado neste arquivo"), mesmo com a detecção do layout e o casamento de linha de pessoa funcionando normalmente. O mesmo arquivo trouxe de quebra um grau de dependência ("OUTROS DEP") e um código de tipo de serviço ("CIR", cirurgia) não previstos. Corrigido: `_ITEM_COPARTICIPACAO_RE` perdeu a fronteira de palavra à esquerda (mantida só à direita) e ganhou "CIR"; "OUTROS DEP" foi acrescentado a `_GRAUS_DEPENDENCIA` (sem isso, mesmo corrigindo o regex do item, a coparticipação dessa dependente cairia por engano na pessoa anterior do bloco, mesmo bug da nota acima). Validado rodando `extrai()` de ponta a ponta contra o arquivo real: 2 beneficiários (KARLA VANESSA R$247,74 + RAPHAELA SOUZ R$183,28), somando R$431,02, batendo exatamente com "Total da Familia" impresso; o arquivo de mensalidade da mesma competência (regex própria, não afetada) continuou extraindo os mesmos 3 beneficiários de sempre.
- **Bug real corrigido (empresa Questor 1879, MARV Empreendimentos, competência 09/2026)**: a coluna "Mat/Orig" (entre o grau e o CPF) vem preenchida em algumas linhas (ex.: "AMANDA DESTROTITULAR 241 067.678.609-05"), e `_PESSOA_COPARTICIPACAO_RE` não previa isso. A linha da pessoa não casava e, quando era a primeira da família, todos os itens dela eram **descartados em silêncio, sem ir pra auditoria** (AMANDA R$ 55,00 e JESSICA R$ 142,48 sumiram). O mesmo arquivo trouxe o código de serviço "ANE" (anestesia), não reconhecido (R$ 208,18 faltando na MARIA LUCIENE). Corrigido aceitando a coluna opcional e acrescentando "ANE" a `_ITEM_COPARTICIPACAO_RE`; validado contra o arquivo real: 6 beneficiários, R$ 2.102,94, batendo com "Total do Titulo" e com cada "Total da Familia" (antes: 4 beneficiários, R$ 1.697,28). Mensalidade do mesmo mês não foi afetada (R$ 5.438,89, 12 beneficiários, batendo com "Total por Contratante"). A importação id 97 (em revisão) foi criada antes da correção e precisa ser refeita.
## Planilha padrão via Questor (SQL)

View File

@ -141,6 +141,19 @@ Particularidades identificadas no PDF de coparticipação analítico (caso 2):
arquivo de mensalidade da mesma competência não foi afetado por este bug
(usa `_LINHA_MENSALIDADE_RE`, uma regex própria) e continuou extraindo
os mesmos 3 beneficiários de antes.
9. **Bug real corrigido (empresa Questor 1879, MARV Empreendimentos,
competência 09/2026)**: a coluna "Mat/Orig", entre o grau e o CPF, vem
preenchida em algumas linhas (ex.: "AMANDA DESTROTITULAR 241
067.678.609-05") — `_PESSOA_COPARTICIPACAO_RE` não previa isso, então a
linha da pessoa não casava e, como era a primeira da família
(`pessoa_atual` = None), todos os itens dela eram descartados em
silêncio, sem nem ir pra auditoria. O mesmo arquivo trouxe o código de
serviço "ANE" (anestesia), que também não era reconhecido. Corrigido
aceitando a coluna opcional e acrescentando "ANE"; validado contra o
arquivo real: 6 beneficiários, R$ 2.102,94, batendo com "Total do
Titulo" e com cada "Total da Familia" impresso (antes: 4 beneficiários,
R$ 1.697,28).
"""
import csv
import re
@ -176,7 +189,11 @@ _LINHA_MENSALIDADE_RE = re.compile(
_PESSOA_COPARTICIPACAO_RE = re.compile(
r"^\s*(?P<benef>\d+\.\d+)(?P<nome>.+?)"
r"(?P<grau>" + "|".join(_GRAUS_DEPENDENCIA) + r")"
r"\s+(?P<cpf>\d{3}\.\d{3}\.\d{3}-\d{2})"
r"\s+(?:\d+\s+)?(?P<cpf>\d{3}\.\d{3}\.\d{3}-\d{2})"
# `(?:\d+\s+)?` = coluna "Mat/Orig", opcional: vazia na maioria das
# linhas, mas preenchida em algumas (ex.: "AMANDA DESTROTITULAR 241
# 067.678.609-05", empresa 1879, competência 09/2026). Sem isso a linha
# da pessoa não casava e todos os itens dela eram descartados em silêncio.
# Confirmado contra o arquivo real: `benef`+`nome`+`grau` vêm colados,
# SEM espaço nenhum entre eles (ex.: "0975.0167003824292ANDREIA
# STORMTITULAR") — só depois do grau é que vem um espaço, antes do CPF.
@ -184,7 +201,9 @@ _PESSOA_COPARTICIPACAO_RE = re.compile(
# o casamento deste relatório usa CPF, não nome (ver
# `chave_casamento_para_tipo`).
)
_ITEM_COPARTICIPACAO_RE = re.compile(r"(?:EXA|CON|HOS|CLI|ODO|MED|CIR)\b")
_ITEM_COPARTICIPACAO_RE = re.compile(r"(?:EXA|CON|HOS|CLI|ODO|MED|CIR|ANE)\b")
# "ANE" (anestesia) visto pela primeira vez na empresa 1879, competência
# 09/2026 (ex.: "...LARISSA FALCAOANE 31602231...").
# Sem fronteira de palavra à esquerda de propósito: confirmado contra um
# segundo arquivo real (cliente Rede Brasil de Mídia OOH, competência
# 08/2026) que esse código de "Tipo Serviço" pode vir colado sem nenhum