feat: adicionar validação de erros no TXT e exibição no comparador DMED
This commit is contained in:
Vendored
BIN
Binary file not shown.
+107
-2
@@ -27,9 +27,18 @@ struct ComparadorApp {
|
||||
divergencias: Vec<Divergencia>,
|
||||
cpfs_so_txt: Vec<CpfExclusivo>,
|
||||
cpfs_so_xls: Vec<CpfExclusivo>,
|
||||
erros_validacao: Vec<ErroValidacao>,
|
||||
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())?;
|
||||
|
||||
Reference in New Issue
Block a user