adding despesas e receitas
This commit is contained in:
parent
b9908b36b7
commit
9a107ce9e8
@ -22,6 +22,11 @@ namespace OpenCand.API.Controllers
|
||||
[EnableRateLimiting(RateLimitingConfig.CandidatoSearchPolicy)]
|
||||
public async Task<CandidatoSearchResult> CandidatoSearch([FromQuery] string q)
|
||||
{
|
||||
if (string.IsNullOrEmpty(q) || q.Length == 1)
|
||||
{
|
||||
throw new ArgumentException("Query parameter 'q' cannot be null/empty.", nameof(q));
|
||||
}
|
||||
|
||||
return await openCandService.SearchCandidatosAsync(q);
|
||||
}
|
||||
|
||||
@ -52,5 +57,17 @@ namespace OpenCand.API.Controllers
|
||||
await Task.Delay(randomWait);
|
||||
return await openCandService.GetCandidatoCpfById(id);
|
||||
}
|
||||
|
||||
[HttpGet("{id}/despesas")]
|
||||
public async Task<DespesasResult> GetCandidatoDespesas([FromRoute] Guid id)
|
||||
{
|
||||
return await openCandService.GetDespesasByIdAndYear(id);
|
||||
}
|
||||
|
||||
[HttpGet("{id}/receitas")]
|
||||
public async Task<ReceitaResult> GetCandidatoReceitas([FromRoute] Guid id)
|
||||
{
|
||||
return await openCandService.GetReceitasByIdAndYear(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,4 +21,14 @@ namespace OpenCand.API.Model
|
||||
{
|
||||
public string Cpf { get; set; }
|
||||
}
|
||||
|
||||
public class DespesasResult
|
||||
{
|
||||
public List<Despesa> Despesas { get; set; }
|
||||
}
|
||||
|
||||
public class ReceitaResult
|
||||
{
|
||||
public List<Receita> Receitas { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ namespace OpenCand.API
|
||||
builder.Services.AddScoped<OpenCandRepository>();
|
||||
builder.Services.AddScoped<CandidatoRepository>();
|
||||
builder.Services.AddScoped<BemCandidatoRepository>();
|
||||
builder.Services.AddScoped<DespesaReceitaRepository>();
|
||||
builder.Services.AddScoped<OpenCandService>();
|
||||
}
|
||||
}
|
||||
|
42
OpenCand.API/Repository/DespesaReceitaRepository.cs
Normal file
42
OpenCand.API/Repository/DespesaReceitaRepository.cs
Normal file
@ -0,0 +1,42 @@
|
||||
using Dapper;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Npgsql;
|
||||
using OpenCand.Core.Models;
|
||||
|
||||
namespace OpenCand.Repository
|
||||
{
|
||||
public class DespesaReceitaRepository : BaseRepository
|
||||
{
|
||||
public DespesaReceitaRepository(IConfiguration configuration) : base(configuration)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task<List<Despesa>> GetDespesasByCandidatoIdYearAsync(Guid idcandidato)
|
||||
{
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
return (await connection.QueryAsync<Despesa>(@"
|
||||
SELECT * FROM despesas_candidato
|
||||
WHERE idcandidato = @idcandidato
|
||||
ORDER BY valor DESC;", new
|
||||
{
|
||||
idcandidato
|
||||
})).AsList();
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<Receita>> GetReceitasByCandidatoIdYearAsync(Guid idcandidato)
|
||||
{
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
return (await connection.QueryAsync<Receita>(@"
|
||||
SELECT * FROM receitas_candidato
|
||||
WHERE idcandidato = @idcandidato
|
||||
ORDER BY valor DESC;", new
|
||||
{
|
||||
idcandidato
|
||||
})).AsList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ namespace OpenCand.API.Services
|
||||
private readonly OpenCandRepository openCandRepository;
|
||||
private readonly CandidatoRepository candidatoRepository;
|
||||
private readonly BemCandidatoRepository bemCandidatoRepository;
|
||||
private readonly DespesaReceitaRepository despesaReceitaRepository;
|
||||
private readonly IConfiguration configuration;
|
||||
private readonly FotosSettings fotoSettings;
|
||||
private readonly ILogger<OpenCandService> logger;
|
||||
@ -20,6 +21,7 @@ namespace OpenCand.API.Services
|
||||
OpenCandRepository openCandRepository,
|
||||
CandidatoRepository candidatoRepository,
|
||||
BemCandidatoRepository bemCandidatoRepository,
|
||||
DespesaReceitaRepository despesaReceitaRepository,
|
||||
IOptions<FotosSettings> fotoSettings,
|
||||
IConfiguration configuration,
|
||||
ILogger<OpenCandService> logger)
|
||||
@ -27,6 +29,7 @@ namespace OpenCand.API.Services
|
||||
this.openCandRepository = openCandRepository;
|
||||
this.candidatoRepository = candidatoRepository;
|
||||
this.bemCandidatoRepository = bemCandidatoRepository;
|
||||
this.despesaReceitaRepository = despesaReceitaRepository;
|
||||
this.fotoSettings = fotoSettings.Value;
|
||||
this.configuration = configuration;
|
||||
this.logger = logger;
|
||||
@ -113,5 +116,33 @@ namespace OpenCand.API.Services
|
||||
Cpf = result
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<DespesasResult> GetDespesasByIdAndYear(Guid idcandidato)
|
||||
{
|
||||
var result = await despesaReceitaRepository.GetDespesasByCandidatoIdYearAsync(idcandidato);
|
||||
if (result == null)
|
||||
{
|
||||
return new DespesasResult();
|
||||
}
|
||||
|
||||
return new DespesasResult()
|
||||
{
|
||||
Despesas = result.OrderByDescending(d => d.Ano).ThenByDescending(d => d.Valor).ToList()
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<ReceitaResult> GetReceitasByIdAndYear(Guid idcandidato)
|
||||
{
|
||||
var result = await despesaReceitaRepository.GetReceitasByCandidatoIdYearAsync(idcandidato);
|
||||
if (result == null)
|
||||
{
|
||||
return new ReceitaResult();
|
||||
}
|
||||
|
||||
return new ReceitaResult()
|
||||
{
|
||||
Receitas = result.OrderByDescending(d => d.Ano).ThenByDescending(d => d.Valor).ToList()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ namespace OpenCand.Core.Models
|
||||
public string Apelido { get; set; }
|
||||
public string SqCandidato { get; set; }
|
||||
public int Ano { get; set; }
|
||||
public string Turno { get; set; }
|
||||
public string TipoEleicao { get; set; }
|
||||
public string SiglaUF { get; set; }
|
||||
public string NomeUE { get; set; }
|
||||
|
25
OpenCand.Core/Models/Despesa.cs
Normal file
25
OpenCand.Core/Models/Despesa.cs
Normal file
@ -0,0 +1,25 @@
|
||||
namespace OpenCand.Core.Models
|
||||
{
|
||||
public class Despesa
|
||||
{
|
||||
public Guid IdDespesa { get; set; }
|
||||
public Guid IdCandidato { get; set; }
|
||||
public int Ano { get; set; }
|
||||
public int Turno { get; set; }
|
||||
|
||||
public string SqCandidato { get; set; }
|
||||
|
||||
public string SgPartido { get; set; }
|
||||
public string TipoFornecedor { get; set; }
|
||||
public string CpfFornecedor { get; set; }
|
||||
public string CnpjFornecedor { get; set; }
|
||||
public string NomeFornecedor { get; set; }
|
||||
public string NomeFornecedorRFB { get; set; }
|
||||
public string MunicipioFornecedor { get; set; }
|
||||
public string TipoDocumento { get; set; }
|
||||
public DateTime? DataDespesa { get; set; }
|
||||
public string OrigemDespesa { get; set; }
|
||||
public string Descricao { get; set; }
|
||||
public float Valor { get; set; }
|
||||
}
|
||||
}
|
26
OpenCand.Core/Models/Receita.cs
Normal file
26
OpenCand.Core/Models/Receita.cs
Normal file
@ -0,0 +1,26 @@
|
||||
namespace OpenCand.Core.Models
|
||||
{
|
||||
public class Receita
|
||||
{
|
||||
public Guid IdReceita { get; set; }
|
||||
public Guid IdCandidato { get; set; }
|
||||
public int Ano { get; set; }
|
||||
public int Turno { get; set; }
|
||||
|
||||
public string SqCandidato { get; set; }
|
||||
|
||||
public string SgPartido { get; set; }
|
||||
public string FonteReceita { get; set; }
|
||||
public string OrigemReceita { get; set; }
|
||||
public string NaturezaReceita { get; set; }
|
||||
public string EspecieReceita { get; set; }
|
||||
public string CpfDoador { get; set; }
|
||||
public string CnpjDoador { get; set; }
|
||||
public string NomeDoador { get; set; }
|
||||
public string NomeDoadorRFB { get; set; }
|
||||
public string MunicipioDoador { get; set; }
|
||||
public DateTime? DataReceita { get; set; }
|
||||
public string Descricao { get; set; }
|
||||
public float Valor { get; set; }
|
||||
}
|
||||
}
|
@ -5,5 +5,7 @@ namespace OpenCand.Config
|
||||
public string CandidatosFolder { get; set; } = string.Empty;
|
||||
public string BensCandidatosFolder { get; set; } = string.Empty;
|
||||
public string RedesSociaisFolder { get; set; } = string.Empty;
|
||||
public string ReceitaCandidatoFolder { get; set; } = string.Empty;
|
||||
public string DespesaCandidatoFolder { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
|
12
OpenCand.ETL/Extensions/StringExtensions.cs
Normal file
12
OpenCand.ETL/Extensions/StringExtensions.cs
Normal file
@ -0,0 +1,12 @@
|
||||
namespace OpenCand.ETL.Extensions
|
||||
{
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static bool IsNullOrEmpty(this string value)
|
||||
{
|
||||
return string.IsNullOrEmpty(value) ||
|
||||
value == "#NE" ||
|
||||
value == "#NULO";
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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}]...");
|
||||
|
@ -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; }
|
||||
|
||||
|
97
OpenCand.ETL/Parser/Models/DespesasCSV.cs
Normal file
97
OpenCand.ETL/Parser/Models/DespesasCSV.cs
Normal 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; }
|
||||
}
|
||||
}
|
94
OpenCand.ETL/Parser/Models/ReceitasCSV.cs
Normal file
94
OpenCand.ETL/Parser/Models/ReceitasCSV.cs
Normal 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; }
|
||||
}
|
||||
}
|
@ -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!");
|
||||
}
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
88
OpenCand.ETL/Parser/ParserServices/DespesaParserService.cs
Normal file
88
OpenCand.ETL/Parser/ParserServices/DespesaParserService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
84
OpenCand.ETL/Parser/ParserServices/ReceitaParserService.cs
Normal file
84
OpenCand.ETL/Parser/ParserServices/ReceitaParserService.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ using OpenCand.Config;
|
||||
using OpenCand.ETL.Contracts;
|
||||
using OpenCand.ETL.Parser.ParserServices;
|
||||
using OpenCand.ETL.Repository;
|
||||
using OpenCand.ETL.Services;
|
||||
using OpenCand.Parser;
|
||||
using OpenCand.Parser.Models;
|
||||
using OpenCand.Parser.Services;
|
||||
@ -60,13 +61,19 @@ namespace OpenCand
|
||||
services.AddTransient<IParserService<CandidatoCSV>, CandidatoParserService>();
|
||||
services.AddTransient<IParserService<BemCandidatoCSV>, BemCandidatoParserService>();
|
||||
services.AddTransient<IParserService<RedeSocialCSV>, RedeSocialParserService>();
|
||||
services.AddTransient<IParserService<DespesasCSV>, DespesaParserService>();
|
||||
services.AddTransient<IParserService<ReceitasCSV>, ReceitaParserService>();
|
||||
services.AddTransient<CsvParserService<CandidatoCSV>>();
|
||||
services.AddTransient<CsvParserService<BemCandidatoCSV>>();
|
||||
services.AddTransient<CsvParserService<RedeSocialCSV>>();
|
||||
services.AddTransient<CsvParserService<DespesasCSV>>();
|
||||
services.AddTransient<CsvParserService<ReceitasCSV>>();
|
||||
services.AddTransient<ParserManager>();
|
||||
services.AddTransient<DespesaReceitaService>();
|
||||
services.AddTransient<CandidatoService>();
|
||||
services.AddTransient<BemCandidatoService>();
|
||||
services.AddTransient<RedeSocialService>();
|
||||
services.AddTransient<DespesaReceitaRepository>();
|
||||
services.AddTransient<CandidatoRepository>();
|
||||
services.AddTransient<BemCandidatoRepository>();
|
||||
services.AddTransient<RedeSocialRepository>();
|
||||
|
@ -49,8 +49,8 @@ namespace OpenCand.Repository
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
await connection.ExecuteAsync(@"
|
||||
INSERT INTO candidato_mapping (idcandidato, cpf, nome, apelido, sqcandidato, ano, tipoeleicao, siglauf, nomeue, cargo, nrcandidato, sgpartido, resultado)
|
||||
VALUES (@idcandidato, @cpf, @nome, @apelido, @sqcandidato, @ano, @tipoeleicao, @siglauf, @nomeue, @cargo, @nrcandidato, @sgpartido, @resultado)
|
||||
INSERT INTO candidato_mapping (idcandidato, cpf, nome, apelido, sqcandidato, ano, turno, tipoeleicao, siglauf, nomeue, cargo, nrcandidato, sgpartido, resultado)
|
||||
VALUES (@idcandidato, @cpf, @nome, @apelido, @sqcandidato, @ano, @turno, @tipoeleicao, @siglauf, @nomeue, @cargo, @nrcandidato, @sgpartido, @resultado)
|
||||
ON CONFLICT DO NOTHING;",
|
||||
new
|
||||
{
|
||||
@ -60,6 +60,7 @@ namespace OpenCand.Repository
|
||||
apelido = candidatoMapping.Apelido,
|
||||
sqcandidato = candidatoMapping.SqCandidato,
|
||||
ano = candidatoMapping.Ano,
|
||||
turno = candidatoMapping.Turno,
|
||||
tipoeleicao = candidatoMapping.TipoEleicao,
|
||||
siglauf = candidatoMapping.SiglaUF,
|
||||
nomeue = candidatoMapping.NomeUE,
|
||||
@ -83,6 +84,18 @@ namespace OpenCand.Repository
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Guid?> GetIdCandidatoBySqCandidato(string sqcandidato)
|
||||
{
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
var query = @"
|
||||
SELECT idcandidato
|
||||
FROM candidato_mapping
|
||||
WHERE sqcandidato = @sqcandidato";
|
||||
return await connection.QueryFirstOrDefaultAsync<Guid>(query, new { sqcandidato });
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Candidato?> GetCandidatoByNome(string nome, DateTime datanascimento)
|
||||
{
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
|
139
OpenCand.ETL/Repository/DespesaReceitaRepository.cs
Normal file
139
OpenCand.ETL/Repository/DespesaReceitaRepository.cs
Normal file
@ -0,0 +1,139 @@
|
||||
using Dapper;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Npgsql;
|
||||
using OpenCand.Core.Models;
|
||||
|
||||
namespace OpenCand.Repository
|
||||
{
|
||||
public class DespesaReceitaRepository : BaseRepository
|
||||
{
|
||||
public DespesaReceitaRepository(IConfiguration configuration) : base(configuration)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task AddDespesaAsync(Despesa despesa)
|
||||
{
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
await connection.ExecuteAsync(@"
|
||||
INSERT INTO despesas_candidato (
|
||||
idcandidato,
|
||||
ano,
|
||||
turno,
|
||||
sqcandidato,
|
||||
sgpartido,
|
||||
tipofornecedor,
|
||||
cnpjfornecedor,
|
||||
cpffornecedor,
|
||||
nomefornecedor,
|
||||
nomefornecedorrfb,
|
||||
municipiofornecedor,
|
||||
tipodocumento,
|
||||
datadespesa,
|
||||
descricao,
|
||||
origemdespesa,
|
||||
valor
|
||||
) VALUES (
|
||||
@idCandidato,
|
||||
@ano,
|
||||
@turno,
|
||||
@sqCandidato,
|
||||
@sgPartido,
|
||||
@tipoFornecedor,
|
||||
@cnpjFornecedor,
|
||||
@cpfFornecedor,
|
||||
@nomeFornecedor,
|
||||
@nomeFornecedorRFB,
|
||||
@municipioFornecedor,
|
||||
@tipoDocumento,
|
||||
@dataDespesa,
|
||||
@descricao,
|
||||
@origemdespesa,
|
||||
@valor
|
||||
)", new
|
||||
{
|
||||
idCandidato = despesa.IdCandidato,
|
||||
ano = despesa.Ano,
|
||||
turno = despesa.Turno,
|
||||
sqCandidato = despesa.SqCandidato,
|
||||
sgPartido = despesa.SgPartido,
|
||||
tipoFornecedor = despesa.TipoFornecedor,
|
||||
cnpjFornecedor = despesa.CnpjFornecedor,
|
||||
cpfFornecedor = despesa.CpfFornecedor,
|
||||
nomeFornecedor = despesa.NomeFornecedor,
|
||||
nomeFornecedorRFB = despesa.NomeFornecedorRFB,
|
||||
municipioFornecedor = despesa.MunicipioFornecedor,
|
||||
tipoDocumento = despesa.TipoDocumento,
|
||||
dataDespesa = despesa.DataDespesa,
|
||||
descricao = despesa.Descricao,
|
||||
origemdespesa = despesa.OrigemDespesa,
|
||||
valor = despesa.Valor
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AddReceitaAsync(Receita receita)
|
||||
{
|
||||
using (var connection = new NpgsqlConnection(ConnectionString))
|
||||
{
|
||||
await connection.ExecuteAsync(@"
|
||||
INSERT INTO receitas_candidato (
|
||||
idcandidato,
|
||||
ano,
|
||||
turno,
|
||||
sqcandidato,
|
||||
sgpartido,
|
||||
fontereceita,
|
||||
origemreceita,
|
||||
naturezareceita,
|
||||
especiereceita,
|
||||
cnpjdoador,
|
||||
cpfdoador,
|
||||
nomedoador,
|
||||
nomedoadorrfb,
|
||||
municipiodoador,
|
||||
datareceita,
|
||||
descricao,
|
||||
valor
|
||||
) VALUES (
|
||||
@idCandidato,
|
||||
@ano,
|
||||
@turno,
|
||||
@sqCandidato,
|
||||
@sgPartido,
|
||||
@fonteReceita,
|
||||
@origemReceita,
|
||||
@naturezaReceita,
|
||||
@especieReceita,
|
||||
@cnpjDoador,
|
||||
@cpfDoador,
|
||||
@nomeDoador,
|
||||
@nomeDoadorRFB,
|
||||
@municipioDoador,
|
||||
@dataReceita,
|
||||
@descricao,
|
||||
@valor
|
||||
)", new
|
||||
{
|
||||
idCandidato = receita.IdCandidato,
|
||||
ano = receita.Ano,
|
||||
turno = receita.Turno,
|
||||
sqCandidato = receita.SqCandidato,
|
||||
sgPartido = receita.SgPartido,
|
||||
fonteReceita = receita.FonteReceita,
|
||||
origemReceita = receita.OrigemReceita,
|
||||
naturezaReceita = receita.NaturezaReceita,
|
||||
especieReceita = receita.EspecieReceita,
|
||||
cnpjDoador = receita.CnpjDoador,
|
||||
cpfDoador = receita.CpfDoador,
|
||||
nomeDoador = receita.NomeDoador,
|
||||
nomeDoadorRFB = receita.NomeDoadorRFB,
|
||||
municipioDoador = receita.MunicipioDoador,
|
||||
dataReceita = receita.DataReceita,
|
||||
descricao = receita.Descricao,
|
||||
valor = receita.Valor
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
54
OpenCand.ETL/Services/DespesaReceitaService.cs
Normal file
54
OpenCand.ETL/Services/DespesaReceitaService.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using OpenCand.Core.Models;
|
||||
using OpenCand.Repository;
|
||||
|
||||
namespace OpenCand.ETL.Services
|
||||
{
|
||||
public class DespesaReceitaService
|
||||
{
|
||||
private readonly DespesaReceitaRepository despesaReceitaRepository;
|
||||
private readonly CandidatoRepository candidatorepository;
|
||||
|
||||
public DespesaReceitaService(DespesaReceitaRepository despesaReceitaRepository, CandidatoRepository candidatoRepository)
|
||||
{
|
||||
this.despesaReceitaRepository = despesaReceitaRepository;
|
||||
this.candidatorepository = candidatoRepository;
|
||||
}
|
||||
|
||||
public async Task AddDespesaAsync(Despesa despesa)
|
||||
{
|
||||
if (despesa == null || string.IsNullOrEmpty(despesa.SqCandidato))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(despesa), "Despesa cannot be null");
|
||||
}
|
||||
|
||||
var idCandidato = await candidatorepository.GetIdCandidatoBySqCandidato(despesa.SqCandidato);
|
||||
if (idCandidato == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentException($"Candidato with SqCandidato {despesa.SqCandidato} not found.");
|
||||
}
|
||||
|
||||
despesa.IdCandidato = (Guid)idCandidato;
|
||||
|
||||
await despesaReceitaRepository.AddDespesaAsync(despesa);
|
||||
}
|
||||
|
||||
public async Task AddReceitaAsync(Receita receita)
|
||||
{
|
||||
if (receita == null || string.IsNullOrEmpty(receita.SqCandidato))
|
||||
{
|
||||
throw new ArgumentNullException(nameof(receita), "Receita cannot be null");
|
||||
}
|
||||
|
||||
var idCandidato = await candidatorepository.GetIdCandidatoBySqCandidato(receita.SqCandidato);
|
||||
if (idCandidato == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentException($"Candidato with SqCandidato {receita.SqCandidato} not found.");
|
||||
}
|
||||
|
||||
receita.IdCandidato = (Guid)idCandidato;
|
||||
|
||||
await despesaReceitaRepository.AddReceitaAsync(receita);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -12,11 +12,15 @@
|
||||
"CsvSettings": {
|
||||
"CandidatosFolder": "data/consulta_cand",
|
||||
"BensCandidatosFolder": "data/bem_candidato",
|
||||
"RedesSociaisFolder": "data/rede_social"
|
||||
"RedesSociaisFolder": "data/rede_social",
|
||||
"DespesaCandidatoFolder": "data/despesas_candidato",
|
||||
"ReceitaCandidatoFolder": "data/receitas_candidato"
|
||||
},
|
||||
"ParserSettings": {
|
||||
"DefaultThreads": 40,
|
||||
"CandidatoCSVThreads": 5
|
||||
"CandidatoCSVThreads": 5,
|
||||
"DepesasCSVThreads": 50,
|
||||
"ReceitasCSVThreads": 50
|
||||
},
|
||||
"BasePath": "sample"
|
||||
}
|
||||
|
89
README.md
89
README.md
@ -8,4 +8,91 @@ OpenCand is built using:
|
||||
* .NET 8 - for parsing initial information from CSV files to the PostgreSQL database using Entity Framework.
|
||||
* .NET Core 8 - for the API
|
||||
* PostgreSQL - for the database
|
||||
* React - for the front-end
|
||||
* React - for the front-end
|
||||
|
||||
## Disponibilidade de dados (Prod)
|
||||
|
||||
* ✅ = Disponível
|
||||
* ❌ = Não disponível
|
||||
* ⛔ = Sem dados
|
||||
|
||||
| Nome do dado | Ano | Disponível? |
|
||||
|-------------------|------|-------------|
|
||||
| Candidatos | 2024 | ✅ |
|
||||
| Bem Candidato | 2024 | ✅ |
|
||||
| Despesas/Receitas | 2024 | ✅ |
|
||||
| Rede Social | 2024 | ✅ |
|
||||
| Fotos | 2024 | ✅ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2022 | ✅ |
|
||||
| Bem Candidato | 2022 | ✅ |
|
||||
| Despesas/Receitas | 2022 | ✅ |
|
||||
| Rede Social | 2022 | ✅ |
|
||||
| Fotos | 2022 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2020 | ✅ |
|
||||
| Bem Candidato | 2020 | ✅ |
|
||||
| Despesas/Receitas | 2020 | ✅ |
|
||||
| Rede Social | 2020 | ✅ |
|
||||
| Fotos | 2020 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2018 | ✅ |
|
||||
| Bem Candidato | 2018 | ✅ |
|
||||
| Despesas/Receitas | 2018 | ❌ |
|
||||
| Rede Social | 2018 | ❌ |
|
||||
| Fotos | 2018 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2016 | ✅ |
|
||||
| Bem Candidato | 2016 | ✅ |
|
||||
| Despesas/Receitas | 2016 | ❌ |
|
||||
| Rede Social | 2016 | ❌ |
|
||||
| Fotos | 2016 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2014 | ✅ |
|
||||
| Bem Candidato | 2014 | ✅ |
|
||||
| Despesas/Receitas | 2014 | ❌ |
|
||||
| Rede Social | 2014 | ❌ |
|
||||
| Fotos | 2014 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2012 | ✅ |
|
||||
| Bem Candidato | 2012 | ✅ |
|
||||
| Despesas/Receitas | 2012 | ❌ |
|
||||
| Rede Social | 2012 | ❌ |
|
||||
| Fotos | 2012 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2010 | ✅ |
|
||||
| Bem Candidato | 2010 | ✅ |
|
||||
| Despesas/Receitas | 2010 | ❌ |
|
||||
| Rede Social | 2010 | ❌ |
|
||||
| Fotos | 2010 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2008 | ✅ |
|
||||
| Bem Candidato | 2008 | ✅ |
|
||||
| Despesas/Receitas | 2008 | ❌ |
|
||||
| Rede Social | 2008 | ❌ |
|
||||
| Fotos | 2008 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2006 | ✅ |
|
||||
| Bem Candidato | 2006 | ✅ |
|
||||
| Despesas/Receitas | 2006 | ❌ |
|
||||
| Rede Social | 2006 | ❌ |
|
||||
| Fotos | 2006 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2004 | ✅ |
|
||||
| Bem Candidato | 2004 | ❌ |
|
||||
| Despesas/Receitas | 2004 | ❌ |
|
||||
| Rede Social | 2004 | ❌ |
|
||||
| Fotos | 2004 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2002 | ✅ |
|
||||
| Bem Candidato | 2002 | ❌ |
|
||||
| Despesas/Receitas | 2002 | ❌ |
|
||||
| Rede Social | 2002 | ❌ |
|
||||
| Fotos | 2002 | ❌ |
|
||||
| - | - | - |
|
||||
| Candidatos | 2000 | ✅ |
|
||||
| Bem Candidato | 2000 | ⛔ |
|
||||
| Despesas/Receitas | 2000 | ⛔ |
|
||||
| Rede Social | 2000 | ⛔ |
|
||||
| Fotos | 2000 | ⛔ |
|
||||
| - | - | - |
|
||||
|
61
db/db.sql
61
db/db.sql
@ -3,6 +3,8 @@ DROP TABLE IF EXISTS candidato_mapping CASCADE;
|
||||
DROP TABLE IF EXISTS rede_social CASCADE;
|
||||
DROP TABLE IF EXISTS candidato CASCADE;
|
||||
DROP TABLE IF EXISTS partido CASCADE;
|
||||
DROP TABLE IF EXISTS despesas_candidato CASCADE;
|
||||
DROP TABLE IF EXISTS receitas_candidato CASCADE;
|
||||
|
||||
CREATE TABLE candidato (
|
||||
idcandidato UUID NOT NULL PRIMARY KEY,
|
||||
@ -25,7 +27,8 @@ CREATE TABLE candidato_mapping (
|
||||
cpf VARCHAR(11),
|
||||
nome VARCHAR(255) NOT NULL,
|
||||
apelido VARCHAR(255),
|
||||
sqcandidato TEXT,
|
||||
sqcandidato VARCHAR(50) NOT NULL,
|
||||
turno VARCHAR(2) NOT NULL,
|
||||
ano INT NOT NULL,
|
||||
tipoeleicao VARCHAR(50),
|
||||
siglauf VARCHAR(2),
|
||||
@ -76,4 +79,58 @@ CREATE TABLE partido (
|
||||
numero INT NOT NULL
|
||||
);
|
||||
CREATE INDEX idx_partido_nome ON partido (nome);
|
||||
CREATE INDEX idx_partido_numero ON partido (numero);
|
||||
CREATE INDEX idx_partido_numero ON partido (numero);
|
||||
|
||||
---- Tables for storing despesas e receitas of candidacies
|
||||
CREATE TABLE despesas_candidato (
|
||||
idreceita UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
idcandidato UUID NOT NULL,
|
||||
ano INT NOT NULL,
|
||||
turno VARCHAR(2) NOT NULL,
|
||||
sqcandidato VARCHAR(50) NOT NULL,
|
||||
sgpartido VARCHAR(50) NOT NULL,
|
||||
tipofornecedor VARCHAR(150),
|
||||
cnpjfornecedor VARCHAR(14),
|
||||
cpffornecedor VARCHAR(11),
|
||||
nomefornecedor VARCHAR(255),
|
||||
nomefornecedorrfb VARCHAR(255),
|
||||
municipiofornecedor VARCHAR(100),
|
||||
tipodocumento VARCHAR(50),
|
||||
datadespesa TIMESTAMPTZ,
|
||||
descricao TEXT,
|
||||
origemdespesa TEXT,
|
||||
valor NUMERIC(20, 2),
|
||||
CONSTRAINT pk_despesas_candidato PRIMARY KEY (idreceita),
|
||||
CONSTRAINT fk_despesas_candidato_candidato FOREIGN KEY (idcandidato) REFERENCES candidato(idcandidato) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
CREATE INDEX idx_despesas_candidato_idcandidato ON despesas_candidato (idcandidato);
|
||||
CREATE INDEX idx_despesas_candidato_ano ON despesas_candidato (ano);
|
||||
CREATE INDEX idx_despesas_candidato_sqcandidato ON despesas_candidato (sqcandidato);
|
||||
CREATE INDEX idx_despesas_candidato_sgpartido ON despesas_candidato (sgpartido);
|
||||
|
||||
CREATE TABLE receitas_candidato (
|
||||
idreceita UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
idcandidato UUID NOT NULL,
|
||||
ano INT NOT NULL,
|
||||
turno VARCHAR(2) NOT NULL,
|
||||
sqcandidato VARCHAR(50) NOT NULL,
|
||||
sgpartido VARCHAR(50) NOT NULL,
|
||||
fontereceita VARCHAR(150),
|
||||
origemreceita VARCHAR(250),
|
||||
naturezareceita VARCHAR(250),
|
||||
especiereceita VARCHAR(250),
|
||||
cnpjdoador VARCHAR(14),
|
||||
cpfdoador VARCHAR(11),
|
||||
nomedoador VARCHAR(255),
|
||||
nomedoadorrfb VARCHAR(255),
|
||||
municipiodoador VARCHAR(100),
|
||||
datareceita TIMESTAMPTZ,
|
||||
descricao TEXT,
|
||||
valor NUMERIC(20, 2),
|
||||
CONSTRAINT pk_receitas_candidato PRIMARY KEY (idreceita),
|
||||
CONSTRAINT fk_receitas_candidato_candidato FOREIGN KEY (idcandidato) REFERENCES candidato(idcandidato) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
CREATE INDEX idx_receitas_candidato_idcandidato ON receitas_candidato (idcandidato);
|
||||
CREATE INDEX idx_receitas_candidato_ano ON receitas_candidato (ano);
|
||||
CREATE INDEX idx_receitas_candidato_sqcandidato ON receitas_candidato (sqcandidato);
|
||||
CREATE INDEX idx_receitas_candidato_sgpartido ON receitas_candidato (sgpartido);
|
Loading…
x
Reference in New Issue
Block a user