diff --git a/dist/DMED-Comparador.exe b/dist/DMED-Comparador.exe index ba8876f..368bfa7 100644 Binary files a/dist/DMED-Comparador.exe and b/dist/DMED-Comparador.exe differ diff --git a/src/bin/gui.rs b/src/bin/gui.rs index 7639ce7..dda7311 100644 --- a/src/bin/gui.rs +++ b/src/bin/gui.rs @@ -27,9 +27,18 @@ struct ComparadorApp { divergencias: Vec, cpfs_so_txt: Vec, cpfs_so_xls: Vec, + erros_validacao: Vec, processando: bool, } +#[derive(Clone)] +struct ErroValidacao { + cpf: String, + nome: String, + valor: f64, + tipo_erro: String, +} + #[derive(Clone)] struct CpfExclusivo { cpf: String, @@ -230,8 +239,42 @@ impl eframe::App for ComparadorApp { 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) - 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.add_space(5.0); @@ -254,6 +297,10 @@ impl eframe::App for ComparadorApp { } impl ComparadorApp { + fn nome_tem_numero(nome: &str) -> bool { + nome.chars().any(|c| c.is_ascii_digit()) + } + fn formatar_valor(valor: f64) -> String { let valor_abs = valor.abs(); let inteiro = valor_abs.trunc() as u64; @@ -285,6 +332,7 @@ impl ComparadorApp { self.divergencias.clear(); self.cpfs_so_txt.clear(); self.cpfs_so_xls.clear(); + self.erros_validacao.clear(); let txt_path = self.arquivo_txt.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)) .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 let margem_tolerancia = 0.01; @@ -390,7 +466,8 @@ impl ComparadorApp { // Resultado let diferenca_total = total_txt - total_xls; - self.resultado = format!( + + let resultado_base = format!( "📊 Estatísticas:\n\ • Total TXT: {} registros\n\ • Total XLS: {} registros únicos\n\ @@ -414,6 +491,13 @@ impl ComparadorApp { 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; } @@ -431,10 +515,31 @@ impl ComparadorApp { 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 XLS: {}", self.cpfs_so_xls.len())?; + writeln!(arquivo, " • Erros de validação no TXT: {}", self.erros_validacao.len())?; writeln!(arquivo)?; writeln!(arquivo, "{}", "=".repeat(120))?; 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 if !self.divergencias.is_empty() { writeln!(arquivo, "🔍 DIVERGÊNCIAS DE VALORES ({} registros)", self.divergencias.len())?;