74 lines
2.9 KiB
Python
74 lines
2.9 KiB
Python
"""
|
|
Leitura do arquivo padrão (leiaute) que o sistema (Questor) importa
|
|
mensalmente, e escrita no mesmo formato. Formato: CSV separado por ';',
|
|
sempre com este cabeçalho:
|
|
|
|
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;
|
|
CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
|
|
|
|
Porta de projects/project/core/leiaute_sistema.py.
|
|
"""
|
|
import csv
|
|
import io
|
|
from typing import List
|
|
|
|
from portal_api.planos_saude.modelos import LinhaSistema
|
|
|
|
CABECALHO = [
|
|
"CODIGOEMPRESA", "NOMEFUNC", "CPFFUNC", "CODIGOOUTEMP", "DATAINICIAL",
|
|
"NOMEDEPENDENTE", "CPFDEPENDENTE", "VALOREMPRESA", "VALOR", "DESCRICAO",
|
|
]
|
|
|
|
|
|
def _decodifica_planilha(caminho_csv: str) -> str:
|
|
"""A planilha padrão do Questor às vezes sai em UTF-8 (com ou sem BOM),
|
|
às vezes em Windows-1252/ANSI — descobrimos isso na prática quando um
|
|
nome com acento (ex.: "GONÇALVES") quebrava a leitura com
|
|
UnicodeDecodeError, sempre tratado genericamente como "arquivo não é a
|
|
planilha padrão" por quem chama esta função. Tenta UTF-8 primeiro (não
|
|
muda nada pro caso comum, sem acentos, onde os dois formatos coincidem
|
|
byte a byte) e cai pra cp1252 só se a decodificação falhar — mesmo
|
|
espírito do `encoding="latin-1"` já usado pelo parser CSV da Unimed."""
|
|
with open(caminho_csv, "rb") as f:
|
|
conteudo = f.read()
|
|
try:
|
|
return conteudo.decode("utf-8-sig")
|
|
except UnicodeDecodeError:
|
|
return conteudo.decode("cp1252")
|
|
|
|
|
|
def le_planilha_padrao(caminho_csv: str) -> List[LinhaSistema]:
|
|
linhas = []
|
|
texto = _decodifica_planilha(caminho_csv)
|
|
with io.StringIO(texto, newline="") as f:
|
|
leitor = csv.DictReader(f, delimiter=";")
|
|
for row in leitor:
|
|
linhas.append(LinhaSistema(
|
|
codigo_empresa=row["CODIGOEMPRESA"].strip(),
|
|
nome_func=row["NOMEFUNC"].strip(),
|
|
cpf_func=row["CPFFUNC"].strip(),
|
|
codigo_out_emp=row["CODIGOOUTEMP"].strip(),
|
|
data_inicial=row["DATAINICIAL"].strip(),
|
|
nome_dependente=row["NOMEDEPENDENTE"].strip(),
|
|
cpf_dependente=row["CPFDEPENDENTE"].strip(),
|
|
valor_empresa=row["VALOREMPRESA"].strip(),
|
|
valor=row["VALOR"].strip(),
|
|
descricao=row["DESCRICAO"].strip(),
|
|
))
|
|
return linhas
|
|
|
|
|
|
def formata_valor_br(valor: float) -> str:
|
|
"""0 -> '0' 83.38 -> '83,38' (mantém o padrão já usado na planilha)"""
|
|
if valor == 0:
|
|
return "0"
|
|
return f"{valor:.2f}".replace(".", ",")
|
|
|
|
|
|
def parse_valor_br(texto: str) -> float:
|
|
"""Inverso de formata_valor_br — '83,38' -> 83.38 '1.234,56' -> 1234.56.
|
|
Usado pra interpretar o "limite de valor"/"% de custeio" digitados pelo
|
|
usuário no formulário de nova importação (ver serializers.py)."""
|
|
texto = (texto or "").strip().replace(".", "").replace(",", ".")
|
|
return float(texto) if texto else 0.0
|