Inclusão do valor de reajuste no plano ITAMED para lançamento da mensalidade

This commit is contained in:
Gabriel 2026-08-31 11:38:49 -03:00
parent 20de8691d4
commit 429a64d4a5
2 changed files with 18 additions and 7 deletions

View File

@ -320,3 +320,9 @@ Pedido do usuário: a Amil Odonto está cadastrada duas vezes no Questor, com `c
- `pipeline.OPERADORAS` ganhou uma segunda chave, `amil_odonto_mensalidade_898` (`codigo_operadora="898"`, `nome="Amil Odonto"`), apontando pra **mesma classe** `AmilOdontoMensalidade` já usada por `amil_odonto_mensalidade` (3758) — nenhum parser novo, nenhuma mudança em `operadoras/amil/odonto_mensalidade.py`. `lista_operadoras()`/`label_operadora()` já cobrem a entrada nova sem alteração (ordenação por `codigo_operadora` numérico já existente coloca "898 - Amil Odonto" na posição certa da lista). - `pipeline.OPERADORAS` ganhou uma segunda chave, `amil_odonto_mensalidade_898` (`codigo_operadora="898"`, `nome="Amil Odonto"`), apontando pra **mesma classe** `AmilOdontoMensalidade` já usada por `amil_odonto_mensalidade` (3758) — nenhum parser novo, nenhuma mudança em `operadoras/amil/odonto_mensalidade.py`. `lista_operadoras()`/`label_operadora()` já cobrem a entrada nova sem alteração (ordenação por `codigo_operadora` numérico já existente coloca "898 - Amil Odonto" na posição certa da lista).
- **Corrigida uma divergência de documentação de longa data, descoberta ao investigar este pedido**: `CLAUDE.md` desta pasta e a skill `importacao-plano-saude` documentavam o cadastro já existente da Amil como "898" desde a primeira versão de cada arquivo — nunca foi esse o valor real em `pipeline.OPERADORAS` (sempre `3758`, confirmado no histórico do git desde o commit que introduziu o campo). Corrigido nos dois lugares; a entrada nova (898) é a única ocorrência legítima desse código no pacote. - **Corrigida uma divergência de documentação de longa data, descoberta ao investigar este pedido**: `CLAUDE.md` desta pasta e a skill `importacao-plano-saude` documentavam o cadastro já existente da Amil como "898" desde a primeira versão de cada arquivo — nunca foi esse o valor real em `pipeline.OPERADORAS` (sempre `3758`, confirmado no histórico do git desde o commit que introduziu o campo). Corrigido nos dois lugares; a entrada nova (898) é a única ocorrência legítima desse código no pacote.
- Nenhuma migração, nenhuma mudança em `models.py`/`views.py`/frontend — o mecanismo de "operadora com múltiplos cadastros compartilhando o mesmo parser" já era suportado de fato pelo desenho existente (`OPERADORAS` é só um dict de registro), só nunca tinha sido usado. - Nenhuma migração, nenhuma mudança em `models.py`/`views.py`/frontend — o mecanismo de "operadora com múltiplos cadastros compartilhando o mesmo parser" já era suportado de fato pelo desenho existente (`OPERADORAS` é só um dict de registro), só nunca tinha sido usado.
### Bug real — Itamed Saúde: reajuste de dependente com motivo "Mudança de faixa" não era somado à mensalidade
Usuário reportou (relatório "OPS - Coparticipação Analítico", competência 08/2026) que a mensalidade extraída de um dependente vinha menor que a real: 492,66 em vez dos 558,39 impressos em "VI mensal."/"VI.Pré-Estab." na linha-resumo da pessoa. A ferramenta já tratava esse cenário pra titular desde um bug anterior (rodada 08/2026, motivo "Variação de custo") — a linha extra "Reajuste - <motivo>" que antecede "Preço pré-estabelecido" precisa ser somada a ela, já que o "Preço pré-estabelecido" vem sem o reajuste embutido.
Causa: `_REAJUSTE_RE` (`operadoras/itamed/saude.py`) só reconhecia o motivo fixo "Variação de custo" — a linha do dependente ("Reajuste - Mudança de faixa" 65,73, referente a mudança de faixa etária) não batia no regex e ficava de fora da soma (492,66 + 65,73 = 558,39, batendo com o valor correto). Corrigido generalizando o regex pra casar qualquer texto depois de "Reajuste -" (`(?P<motivo>Reajuste\s*-\s*.+?)\s+(?P<valor>[\d.,]+)\s*$`), usando o motivo capturado como `rubrica` do lançamento em vez do texto fixo "Reajuste - Variação de custo" — a lógica de somar como `tipo_lancamento="mensalidade"` não mudou, só passou a valer pra qualquer motivo de reajuste, não só um.

View File

@ -39,16 +39,21 @@ pdfplumber com `layout=True`, ver `_pdf_para_linhas`):
mas a agregação soma por precaução, mesmo padrão dos outros parsers). mas a agregação soma por precaução, mesmo padrão dos outros parsers).
5. Quando há reajuste de mensalidade no mês, a mini-tabela ganha uma 5. Quando há reajuste de mensalidade no mês, a mini-tabela ganha uma
linha extra "Reajuste - Variação de custo <valor>" ANTES de "Preço linha extra "Reajuste - <motivo> <valor>" ANTES de "Preço
pré-estabelecido" — o valor desta linha é a diferença do reajuste, e pré-estabelecido" — o valor desta linha é a diferença do reajuste, e
"Preço pré-estabelecido" nesse caso já vem SEM o reajuste embutido "Preço pré-estabelecido" nesse caso já vem SEM o reajuste embutido
(ex.: reajuste 64,22 + preço pré-estabelecido 900,65 = mensalidade (ex.: reajuste 64,22 + preço pré-estabelecido 900,65 = mensalidade
real 964,87, que é o valor que aparece em "VI.Pré-Estab."/"VI mensal." real 964,87, que é o valor que aparece em "VI.Pré-Estab."/"VI mensal."
na linha-resumo da pessoa). Por isso o valor de "Reajuste - Variação na linha-resumo da pessoa). Por isso o valor de "Reajuste - <motivo>"
de custo" também é lançado como `tipo_lancamento="mensalidade"` (soma também é lançado como `tipo_lancamento="mensalidade"` (soma com
com "Preço pré-estabelecido" na agregação por indivíduo) — sem isso, a "Preço pré-estabelecido" na agregação por indivíduo) — sem isso, a
mensalidade extraída ficava sistematicamente menor que a real em todo mensalidade extraída ficava sistematicamente menor que a real em todo
mês com reajuste, bug real visto com o arquivo de 08/2026. mês com reajuste, bug real visto com o arquivo de 08/2026 (motivo
"Variação de custo", visto em titular) e confirmado de novo em
08/2026 com o motivo "Mudança de faixa" (mudança de faixa etária,
visto em dependente) — o motivo em si varia (pelo menos "Variação de
custo" e "Mudança de faixa" já vistos), por isso `_REAJUSTE_RE` casa
qualquer texto depois de "Reajuste -", não só um motivo fixo.
""" """
import re import re
from typing import Dict, List, Tuple from typing import Dict, List, Tuple
@ -68,7 +73,7 @@ _PESSOA_RE = re.compile(
) )
_PREESTAB_RE = re.compile(r'^\s*Pre[çc]o pr[ée]-estabelecido\s+(?P<valor>[\d.,]+)') _PREESTAB_RE = re.compile(r'^\s*Pre[çc]o pr[ée]-estabelecido\s+(?P<valor>[\d.,]+)')
_COPART_RE = re.compile(r'^\s*Co-participa[çc][ãa]o\s+(?P<valor>[\d.,]+)') _COPART_RE = re.compile(r'^\s*Co-participa[çc][ãa]o\s+(?P<valor>[\d.,]+)')
_REAJUSTE_RE = re.compile(r'^\s*Reajuste\s*-\s*Varia[çc][ãa]o de custo\s+(?P<valor>[\d.,]+)') _REAJUSTE_RE = re.compile(r'^\s*(?P<motivo>Reajuste\s*-\s*.+?)\s+(?P<valor>[\d.,]+)\s*$')
def _valor_para_float(texto: str) -> float: def _valor_para_float(texto: str) -> float:
@ -122,7 +127,7 @@ class ItamedSaude(OperadoraParser):
nome=pessoa_atual["nome"], nome=pessoa_atual["nome"],
cpf="", cpf="",
tipo=pessoa_atual["tipo"], tipo=pessoa_atual["tipo"],
rubrica="Reajuste - Variação de custo", rubrica=m_reajuste.group("motivo").strip(),
valor=_valor_para_float(m_reajuste.group("valor")), valor=_valor_para_float(m_reajuste.group("valor")),
tipo_lancamento="mensalidade", tipo_lancamento="mensalidade",
numero_titular=pessoa_atual["numero_titular"], numero_titular=pessoa_atual["numero_titular"],