feat: adicionar validação de erros no TXT e exibição no comparador DMED

This commit is contained in:
FelipeCN
2026-01-30 14:02:14 -03:00
parent 67154ba8d4
commit 870f120319
2 changed files with 107 additions and 2 deletions
BIN
View File
Binary file not shown.
+107 -2
View File
@@ -27,9 +27,18 @@ struct ComparadorApp {
divergencias: Vec<Divergencia>, divergencias: Vec<Divergencia>,
cpfs_so_txt: Vec<CpfExclusivo>, cpfs_so_txt: Vec<CpfExclusivo>,
cpfs_so_xls: Vec<CpfExclusivo>, cpfs_so_xls: Vec<CpfExclusivo>,
erros_validacao: Vec<ErroValidacao>,
processando: bool, processando: bool,
} }
#[derive(Clone)]
struct ErroValidacao {
cpf: String,
nome: String,
valor: f64,
tipo_erro: String,
}
#[derive(Clone)] #[derive(Clone)]
struct CpfExclusivo { struct CpfExclusivo {
cpf: String, cpf: String,
@@ -230,8 +239,42 @@ impl eframe::App for ComparadorApp {
ui.add_space(10.0); ui.add_space(10.0);
} }
// Erros de validação
if !self.erros_validacao.is_empty() {
ui.separator();
ui.add_space(5.0);
ui.heading(format!("❌ Erros de validação no TXT: {}", self.erros_validacao.len()));
ui.label("Estes registros possuem problemas que precisam ser corrigidos");
ui.add_space(5.0);
egui::ScrollArea::vertical()
.max_height(150.0)
.show(ui, |ui| {
egui::Grid::new("erros_validacao_grid")
.striped(true)
.min_col_width(100.0)
.show(ui, |ui| {
ui.strong("CPF");
ui.strong("Nome");
ui.strong("Valor (R$)");
ui.strong("Erro");
ui.end_row();
for erro in &self.erros_validacao {
ui.label(&erro.cpf);
ui.label(&erro.nome);
ui.label(Self::formatar_valor(erro.valor));
ui.colored_label(egui::Color32::RED, &erro.tipo_erro);
ui.end_row();
}
});
});
ui.add_space(10.0);
}
// Botão para exportar (mostra se tiver qualquer resultado) // Botão para exportar (mostra se tiver qualquer resultado)
if !self.divergencias.is_empty() || !self.cpfs_so_txt.is_empty() || !self.cpfs_so_xls.is_empty() { if !self.divergencias.is_empty() || !self.cpfs_so_txt.is_empty() || !self.cpfs_so_xls.is_empty() || !self.erros_validacao.is_empty() {
ui.separator(); ui.separator();
ui.add_space(5.0); ui.add_space(5.0);
@@ -254,6 +297,10 @@ impl eframe::App for ComparadorApp {
} }
impl ComparadorApp { impl ComparadorApp {
fn nome_tem_numero(nome: &str) -> bool {
nome.chars().any(|c| c.is_ascii_digit())
}
fn formatar_valor(valor: f64) -> String { fn formatar_valor(valor: f64) -> String {
let valor_abs = valor.abs(); let valor_abs = valor.abs();
let inteiro = valor_abs.trunc() as u64; let inteiro = valor_abs.trunc() as u64;
@@ -285,6 +332,7 @@ impl ComparadorApp {
self.divergencias.clear(); self.divergencias.clear();
self.cpfs_so_txt.clear(); self.cpfs_so_txt.clear();
self.cpfs_so_xls.clear(); self.cpfs_so_xls.clear();
self.erros_validacao.clear();
let txt_path = self.arquivo_txt.as_ref().unwrap().clone(); let txt_path = self.arquivo_txt.as_ref().unwrap().clone();
let xls_path = self.arquivo_xls.as_ref().unwrap().clone(); let xls_path = self.arquivo_xls.as_ref().unwrap().clone();
@@ -335,6 +383,34 @@ impl ComparadorApp {
.filter(|cpf| !mapa_txt.contains_key(**cpf)) .filter(|cpf| !mapa_txt.contains_key(**cpf))
.count(); .count();
// Validações no TXT
for pessoa in &pessoas_txt {
let mut erros = Vec::new();
// Validação 1: Valor zerado
if pessoa.valor == 0.0 {
erros.push("Valor zerado");
}
// Validação 2: Nome com número
if Self::nome_tem_numero(&pessoa.nome) {
erros.push("Nome contém número");
}
// Se houver erros, adiciona à lista
if !erros.is_empty() {
self.erros_validacao.push(ErroValidacao {
cpf: pessoa.cpf.clone(),
nome: pessoa.nome.clone(),
valor: pessoa.valor,
tipo_erro: erros.join(" | "),
});
}
}
// Ordena erros por CPF
self.erros_validacao.sort_by(|a, b| a.cpf.cmp(&b.cpf));
// Encontra divergências // Encontra divergências
let margem_tolerancia = 0.01; let margem_tolerancia = 0.01;
@@ -390,7 +466,8 @@ impl ComparadorApp {
// Resultado // Resultado
let diferenca_total = total_txt - total_xls; let diferenca_total = total_txt - total_xls;
self.resultado = format!(
let resultado_base = format!(
"📊 Estatísticas:\n\ "📊 Estatísticas:\n\
• Total TXT: {} registros\n\ • Total TXT: {} registros\n\
• Total XLS: {} registros únicos\n\ • Total XLS: {} registros únicos\n\
@@ -414,6 +491,13 @@ impl ComparadorApp {
Self::formatar_valor(diferenca_total) Self::formatar_valor(diferenca_total)
); );
self.resultado = if !self.erros_validacao.is_empty() {
format!("{}\n\n❌ ATENÇÃO: {} erros de validação encontrados no TXT!",
resultado_base, self.erros_validacao.len())
} else {
resultado_base
};
self.processando = false; self.processando = false;
} }
@@ -431,10 +515,31 @@ impl ComparadorApp {
writeln!(arquivo, " • Total de divergências de valores: {}", self.divergencias.len())?; writeln!(arquivo, " • Total de divergências de valores: {}", self.divergencias.len())?;
writeln!(arquivo, " • CPFs apenas no TXT: {}", self.cpfs_so_txt.len())?; writeln!(arquivo, " • CPFs apenas no TXT: {}", self.cpfs_so_txt.len())?;
writeln!(arquivo, " • CPFs apenas no XLS: {}", self.cpfs_so_xls.len())?; writeln!(arquivo, " • CPFs apenas no XLS: {}", self.cpfs_so_xls.len())?;
writeln!(arquivo, " • Erros de validação no TXT: {}", self.erros_validacao.len())?;
writeln!(arquivo)?; writeln!(arquivo)?;
writeln!(arquivo, "{}", "=".repeat(120))?; writeln!(arquivo, "{}", "=".repeat(120))?;
writeln!(arquivo)?; writeln!(arquivo)?;
// Erros de validação
if !self.erros_validacao.is_empty() {
writeln!(arquivo, "❌ ERROS DE VALIDAÇÃO NO TXT ({} registros)", self.erros_validacao.len())?;
writeln!(arquivo, " Estes registros possuem problemas que DEVEM ser corrigidos")?;
writeln!(arquivo, "{}", "-".repeat(120))?;
writeln!(arquivo, "{:<15} {:<40} {:>15} {:<30}", "CPF", "Nome", "Valor (R$)", "Erro")?;
writeln!(arquivo, "{}", "-".repeat(120))?;
for erro in &self.erros_validacao {
writeln!(arquivo, "{:<15} {:<40} {:>15} {:<30}",
erro.cpf,
erro.nome,
Self::formatar_valor(erro.valor),
erro.tipo_erro)?;
}
writeln!(arquivo)?;
writeln!(arquivo, "{}", "=".repeat(120))?;
writeln!(arquivo)?;
}
// Divergências de valores // Divergências de valores
if !self.divergencias.is_empty() { if !self.divergencias.is_empty() {
writeln!(arquivo, "🔍 DIVERGÊNCIAS DE VALORES ({} registros)", self.divergencias.len())?; writeln!(arquivo, "🔍 DIVERGÊNCIAS DE VALORES ({} registros)", self.divergencias.len())?;