adding despesas e receitas

This commit is contained in:
2025-06-07 11:56:03 -03:00
parent b9908b36b7
commit 9a107ce9e8
29 changed files with 922 additions and 58 deletions

View File

@@ -1,15 +0,0 @@
using CsvHelper.Configuration;
using OpenCand.Parser.Models;
using System.Globalization;
namespace OpenCand.Parser.CsvMappers
{
public class BemCandidatoMap : ClassMap<BemCandidatoCSV>
{
public BemCandidatoMap()
{
AutoMap(CultureInfo.InvariantCulture);
// Explicitly handle any special mappings if needed
}
}
}

View File

@@ -1,15 +0,0 @@
using CsvHelper.Configuration;
using OpenCand.Parser.Models;
using System.Globalization;
namespace OpenCand.Parser.CsvMappers
{
public class CandidatoMap : ClassMap<CandidatoCSV>
{
public CandidatoMap()
{
AutoMap(CultureInfo.InvariantCulture);
// Explicitly handle any special mappings if needed
}
}
}

View File

@@ -1,14 +0,0 @@
using System.Globalization;
using CsvHelper.Configuration;
using OpenCand.Parser.Models;
namespace OpenCand.ETL.Parser.CsvMappers
{
public class RedeSocialMap : ClassMap<BemCandidatoCSV>
{
public RedeSocialMap()
{
AutoMap(CultureInfo.InvariantCulture);
}
}
}

View File

@@ -73,8 +73,10 @@ namespace OpenCand.Parser.Services
{
if (columns.Length > headerCount)
{
logger.LogCritical($"FixCsvFile - Line {i + 1} has {columns.Length} columns, expected {headerCount}. Halting process.");
return string.Empty; // Critical error, cannot fix this line => needs manual intervention
// logger.LogCritical($"FixCsvFile - Line {i + 1} has {columns.Length} columns, expected {headerCount}. Halting process.");
// return string.Empty; // Critical error, cannot fix this line => needs manual intervention
// consider as normal line
break;
}
logger.LogWarning($"FixCsvFile - Line {i + 1} has {columns.Length} columns, expected {headerCount}. Attempting to fix [i = {lineJump}]...");

View File

@@ -11,6 +11,9 @@ namespace OpenCand.Parser.Models
[Name("TP_ABRANGENCIA")]
public string TipoAbrangencia { get; set; }
[Name("NR_TURNO")]
public string Turno { get; set; }
[Name("SG_UF")]
public string SiglaUF { get; set; }

View File

@@ -0,0 +1,97 @@
using CsvHelper.Configuration.Attributes;
namespace OpenCand.Parser.Models
{
public class DespesasCSV
{
[Name("AA_ELEICAO")]
public int AnoEleicao { get; set; }
[Name("ST_TURNO")]
public string Turno { get; set; }
[Name("DT_PRESTACAO_CONTAS")]
public string DataPrestacaoContas { get; set; }
[Name("SQ_PRESTADOR_CONTAS")]
public string SequencialPrestadorContas { get; set; }
[Name("SG_UF")]
public string SiglaUF { get; set; }
[Name("NM_UE")]
public string NomeUE { get; set; }
[Name("NR_CNPJ_PRESTADOR_CONTA")]
public string CnpjPrestadorConta { get; set; }
[Name("SQ_CANDIDATO")]
public string SequencialCandidato { get; set; }
[Name("NR_CPF_CANDIDATO")]
public string CpfCandidato { get; set; }
[Name("SG_PARTIDO")]
public string SiglaPartido { get; set; }
[Name("DS_TIPO_FORNECEDOR")]
public string TipoFornecedor { get; set; }
[Name("CD_CNAE_FORNECEDOR")]
public string CodigoCnaeFornecedor { get; set; }
[Name("DS_CNAE_FORNECEDOR")]
public string DescricaoCnaeFornecedor { get; set; }
[Name("NR_CPF_CNPJ_FORNECEDOR")]
public string CpfCnpjFornecedor { get; set; }
[Name("NM_FORNECEDOR")]
public string NomeFornecedor { get; set; }
[Name("NM_FORNECEDOR_RFB")]
public string NomeFornecedorRFB { get; set; }
[Name("SG_UF_FORNECEDOR")]
public string SiglaUFFornecedor { get; set; }
[Name("NM_MUNICIPIO_FORNECEDOR")]
public string NomeMunicipioFornecedor { get; set; }
[Name("SQ_CANDIDATO_FORNECEDOR")]
public string SequencialCandidatoFornecedor { get; set; }
[Name("NR_CANDIDATO_FORNECEDOR")]
public string NumeroCandidatoFornecedor { get; set; }
[Name("DS_CARGO_FORNECEDOR")]
public string CargoFornecedor { get; set; }
[Name("NR_PARTIDO_FORNECEDOR")]
public string NumeroPartidoFornecedor { get; set; }
[Name("SG_PARTIDO_FORNECEDOR")]
public string SiglaPartidoFornecedor { get; set; }
[Name("NM_PARTIDO_FORNECEDOR")]
public string NomePartidoFornecedor { get; set; }
[Name("DS_TIPO_DOCUMENTO")]
public string TipoDocumento { get; set; }
[Name("DS_ORIGEM_DESPESA")]
public string OrigemDespesa { get; set; }
[Name("SQ_DESPESA")]
public string SequencialDespesa { get; set; }
[Name("DT_DESPESA")]
public string DataDespesa { get; set; }
[Name("DS_DESPESA")]
public string DescricaoDespesa { get; set; }
[Name("VR_DESPESA_CONTRATADA")]
public float ValorDespesaContratada { get; set; }
}
}

View File

@@ -0,0 +1,94 @@
using CsvHelper.Configuration.Attributes;
namespace OpenCand.Parser.Models
{
public class ReceitasCSV
{
[Name("AA_ELEICAO")]
public int AnoEleicao { get; set; }
[Name("ST_TURNO")]
public string Turno { get; set; }
[Name("SQ_PRESTADOR_CONTAS")]
public string SequencialPrestadorContas { get; set; }
[Name("SG_UF")]
public string SiglaUF { get; set; }
[Name("NM_UE")]
public string NomeUE { get; set; }
[Name("NR_CNPJ_PRESTADOR_CONTA")]
public string CnpjPrestadorConta { get; set; }
[Name("SQ_CANDIDATO")]
public string SequencialCandidato { get; set; }
[Name("NR_CPF_CANDIDATO")]
public string CpfCandidato { get; set; }
[Name("SG_PARTIDO")]
public string SiglaPartido { get; set; }
[Name("DS_FONTE_RECEITA")]
public string FonteReceita { get; set; }
[Name("DS_ORIGEM_RECEITA")]
public string OrigemReceita { get; set; }
[Name("DS_NATUREZA_RECEITA")]
public string NaturezaReceita { get; set; }
[Name("DS_ESPECIE_RECEITA")]
public string EspecieReceita { get; set; }
[Name("CD_CNAE_DOADOR")]
public string CodigoCnaeDoador { get; set; }
[Name("DS_CNAE_DOADOR")]
public string DescricaoCnaeDoador { get; set; }
[Name("NR_CPF_CNPJ_DOADOR")]
public string CpfCnpjDoador { get; set; }
[Name("NM_DOADOR")]
public string NomeDoador { get; set; }
[Name("NM_DOADOR_RFB")]
public string NomeDoadorRFB { get; set; }
[Name("SG_UF_DOADOR")]
public string SiglaUFDoaror { get; set; }
[Name("NM_MUNICIPIO_DOADOR")]
public string NomeMunicipioDoador { get; set; }
[Name("SQ_CANDIDATO_DOADOR")]
public string SequencialCandidatoDoador { get; set; }
[Name("SG_PARTIDO_DOADOR")]
public string SiglaPartidoDoador { get; set; }
[Name("NR_RECIBO_DOACAO")]
public string NumeroReciboDoacao { get; set; }
[Name("NR_DOCUMENTO_DOACAO")]
public string NumeroDocumentoDoacao { get; set; }
[Name("SQ_RECEITA")]
public string SequencialReceita { get; set; }
[Name("DT_RECEITA")]
public string DataReceita { get; set; }
[Name("DS_RECEITA")]
public string DescricaoReceita { get; set; }
[Name("VR_RECEITA")]
public float ValorReceita { get; set; }
[Name("DS_GENERO")]
public string Genero { get; set; }
}
}

View File

@@ -15,6 +15,8 @@ namespace OpenCand.Parser
private readonly CsvParserService<CandidatoCSV> candidatoParserService;
private readonly CsvParserService<BemCandidatoCSV> bemCandidatoParserService;
private readonly CsvParserService<RedeSocialCSV> redeSocialParserService;
private readonly CsvParserService<DespesasCSV> despesaParserService;
private readonly CsvParserService<ReceitasCSV> receitaParserService;
private readonly string BasePath;
@@ -24,7 +26,9 @@ namespace OpenCand.Parser
IConfiguration configuration,
CsvParserService<CandidatoCSV> candidatoParserService,
CsvParserService<BemCandidatoCSV> bemCandidatoParserService,
CsvParserService<RedeSocialCSV> redeSocialParserService)
CsvParserService<RedeSocialCSV> redeSocialParserService,
CsvParserService<DespesasCSV> despesaParserService,
CsvParserService<ReceitasCSV> receitaParserService)
{
this.logger = logger;
this.csvSettings = csvSettings.Value;
@@ -32,6 +36,8 @@ namespace OpenCand.Parser
this.candidatoParserService = candidatoParserService;
this.bemCandidatoParserService = bemCandidatoParserService;
this.redeSocialParserService = redeSocialParserService;
this.despesaParserService = despesaParserService;
this.receitaParserService = receitaParserService;
// Get the base path from either SampleFolder in csvSettings or the BasePath in configuration
BasePath = configuration.GetValue<string>("BasePath") ?? string.Empty;
@@ -49,10 +55,14 @@ namespace OpenCand.Parser
var candidatosDirectory = Path.Combine(BasePath, csvSettings.CandidatosFolder);
var bensCandidatosDirectory = Path.Combine(BasePath, csvSettings.BensCandidatosFolder);
var redesSociaisDirectory = Path.Combine(BasePath, csvSettings.RedesSociaisFolder);
var despesasDirectory = Path.Combine(BasePath, csvSettings.DespesaCandidatoFolder);
var receitasDirectory = Path.Combine(BasePath, csvSettings.ReceitaCandidatoFolder);
await ParseFolder(candidatosDirectory, candidatoParserService);
await ParseFolder(bensCandidatosDirectory, bemCandidatoParserService);
await ParseFolder(redesSociaisDirectory, redeSocialParserService);
//await ParseFolder(candidatosDirectory, candidatoParserService);
//await ParseFolder(bensCandidatosDirectory, bemCandidatoParserService);
//await ParseFolder(redesSociaisDirectory, redeSocialParserService);
await ParseFolder(despesasDirectory, despesaParserService);
await ParseFolder(receitasDirectory, receitaParserService);
logger.LogInformation("ParseFullDataAsync - Full data parsing completed!");
}

View File

@@ -5,6 +5,7 @@ using OpenCand.ETL.Contracts;
using OpenCand.Parser.Models;
using OpenCand.Services;
using OpenCand.Parser.Services;
using OpenCand.ETL.Extensions;
namespace OpenCand.ETL.Parser.ParserServices
{
@@ -25,7 +26,7 @@ namespace OpenCand.ETL.Parser.ParserServices
{
// Parse decimal value
decimal? valor = null;
if (!string.IsNullOrEmpty(record.ValorBemCandidato))
if (!record.ValorBemCandidato.IsNullOrEmpty())
{
string normalizedValue = record.ValorBemCandidato.Replace(".", "").Replace(",", ".");
if (decimal.TryParse(normalizedValue, NumberStyles.Any, CultureInfo.InvariantCulture, out var parsedValue))

View File

@@ -63,6 +63,7 @@ namespace OpenCand.ETL.Parser.ParserServices
Apelido = record.Apelido,
SqCandidato = record.SequencialCandidato,
Ano = record.AnoEleicao,
Turno = record.Turno,
TipoEleicao = record.TipoAbrangencia,
NomeUE = record.NomeUE,
SiglaUF = record.SiglaUF,

View File

@@ -0,0 +1,88 @@
using Microsoft.Extensions.Logging;
using OpenCand.Core.Models;
using OpenCand.ETL.Contracts;
using OpenCand.ETL.Extensions;
using OpenCand.ETL.Services;
using OpenCand.Parser.Models;
namespace OpenCand.ETL.Parser.ParserServices
{
public class DespesaParserService : IParserService<DespesasCSV>
{
private readonly ILogger<DespesaParserService> logger;
private readonly DespesaReceitaService despesaReceitaService;
public DespesaParserService(
ILogger<DespesaParserService> logger,
DespesaReceitaService despesaReceitaService)
{
this.logger = logger;
this.despesaReceitaService = despesaReceitaService;
}
public async Task ParseObject(DespesasCSV record)
{
var despesa = new Despesa
{
SgPartido = record.SiglaPartido,
Ano = record.AnoEleicao,
Turno = int.Parse(record.Turno),
Descricao = record.DescricaoDespesa,
OrigemDespesa = record.OrigemDespesa,
MunicipioFornecedor = record.NomeMunicipioFornecedor,
NomeFornecedor = record.NomeFornecedor,
NomeFornecedorRFB = record.NomeFornecedorRFB,
SqCandidato = record.SequencialCandidato,
TipoDocumento = record.TipoDocumento,
TipoFornecedor = record.TipoFornecedor,
Valor = record.ValorDespesaContratada / 100
};
if (DateTime.TryParse(record.DataDespesa, out var dataDespesa))
{
despesa.DataDespesa = dataDespesa;
}
else
{
despesa.DataDespesa = null;
}
if (record.CpfCnpjFornecedor.Length == 0 || record.CpfCnpjFornecedor == "-4")
{
despesa.CpfFornecedor = null;
despesa.CnpjFornecedor = null;
}
else if (record.CpfCnpjFornecedor.Length == 11)
{
despesa.CpfFornecedor = record.CpfCnpjFornecedor;
despesa.CnpjFornecedor = null;
}
else if (record.CpfCnpjFornecedor.Length == 14)
{
despesa.CnpjFornecedor = record.CpfCnpjFornecedor;
despesa.CpfFornecedor = null;
}
if (despesa.Descricao.IsNullOrEmpty())
despesa.Descricao = null;
if (despesa.OrigemDespesa.IsNullOrEmpty())
despesa.OrigemDespesa = null;
if (despesa.MunicipioFornecedor.IsNullOrEmpty())
despesa.MunicipioFornecedor = null;
if (despesa.NomeFornecedor.IsNullOrEmpty())
despesa.NomeFornecedor = null;
if (despesa.NomeFornecedorRFB.IsNullOrEmpty())
despesa.NomeFornecedorRFB = null;
if (despesa.TipoDocumento.IsNullOrEmpty())
despesa.TipoDocumento = null;
if (despesa.CpfFornecedor.IsNullOrEmpty())
despesa.CpfFornecedor = null;
if (despesa.CnpjFornecedor.IsNullOrEmpty())
despesa.CnpjFornecedor = null;
if (despesa.TipoFornecedor.IsNullOrEmpty())
despesa.TipoFornecedor = null;
await despesaReceitaService.AddDespesaAsync(despesa);
}
}
}

View File

@@ -0,0 +1,84 @@
using Microsoft.Extensions.Logging;
using OpenCand.Core.Models;
using OpenCand.ETL.Contracts;
using OpenCand.ETL.Extensions;
using OpenCand.ETL.Services;
using OpenCand.Parser.Models;
namespace OpenCand.ETL.Parser.ParserServices
{
public class ReceitaParserService : IParserService<ReceitasCSV>
{
private readonly ILogger<ReceitaParserService> logger;
private readonly DespesaReceitaService despesaReceitaService;
public ReceitaParserService(
ILogger<ReceitaParserService> logger,
DespesaReceitaService despesaReceitaService)
{
this.logger = logger;
this.despesaReceitaService = despesaReceitaService;
}
public async Task ParseObject(ReceitasCSV record)
{
var receita = new Receita
{
EspecieReceita = record.EspecieReceita,
MunicipioDoador = record.NomeMunicipioDoador,
SgPartido = record.SiglaPartido,
FonteReceita = record.FonteReceita,
NaturezaReceita = record.NaturezaReceita,
Ano = record.AnoEleicao,
Descricao = record.DescricaoReceita,
NomeDoador = record.NomeDoador,
NomeDoadorRFB = record.NomeDoadorRFB,
OrigemReceita = record.OrigemReceita,
Turno = int.Parse(record.Turno),
SqCandidato = record.SequencialCandidato,
Valor = record.ValorReceita / 100
};
if (DateTime.TryParse(record.DataReceita, out var dataReceita))
{
receita.DataReceita = dataReceita;
}
else
{
receita.DataReceita = null;
}
if (record.CpfCnpjDoador.Length == 0 || record.CpfCnpjDoador == "-4") {
receita.CpfDoador = null;
receita.CnpjDoador = null;
}
else if (record.CpfCnpjDoador.Length == 11)
{
receita.CpfDoador = record.CpfCnpjDoador;
receita.CnpjDoador = null;
}
else if (record.CpfCnpjDoador.Length == 14)
{
receita.CnpjDoador = record.CpfCnpjDoador;
receita.CpfDoador = null;
}
if (receita.Descricao.IsNullOrEmpty())
receita.Descricao = null;
if (receita.MunicipioDoador.IsNullOrEmpty())
receita.MunicipioDoador = null;
if (receita.NomeDoador.IsNullOrEmpty())
receita.NomeDoador = null;
if (receita.NomeDoadorRFB.IsNullOrEmpty())
receita.NomeDoadorRFB = null;
if (receita.OrigemReceita.IsNullOrEmpty())
receita.OrigemReceita = null;
if (receita.CpfDoador.IsNullOrEmpty())
receita.CpfDoador = null;
if (receita.CnpjDoador.IsNullOrEmpty())
receita.CnpjDoador = null;
await despesaReceitaService.AddReceitaAsync(receita);
}
}
}