Files
opencand/OpenCand.API/Services/OpenCandService.cs
2025-09-12 21:18:36 -03:00

216 lines
7.9 KiB
C#

using Microsoft.Extensions.Options;
using OpenCand.API.Config;
using OpenCand.API.Model;
using OpenCand.API.Repository;
using OpenCand.Core.Models;
using OpenCand.Repository;
namespace OpenCand.API.Services
{
public class OpenCandService
{
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;
public OpenCandService(
OpenCandRepository openCandRepository,
CandidatoRepository candidatoRepository,
BemCandidatoRepository bemCandidatoRepository,
DespesaReceitaRepository despesaReceitaRepository,
IOptions<FotosSettings> fotoSettings,
IConfiguration configuration,
ILogger<OpenCandService> logger)
{
this.openCandRepository = openCandRepository;
this.candidatoRepository = candidatoRepository;
this.bemCandidatoRepository = bemCandidatoRepository;
this.despesaReceitaRepository = despesaReceitaRepository;
this.fotoSettings = fotoSettings.Value;
this.configuration = configuration;
this.logger = logger;
}
public async Task<OpenCandStats> GetOpenCandStatsAsync()
{
logger.LogInformation("Getting OpenCand stats");
return await openCandRepository.GetOpenCandStatsAsync();
}
public async Task<DataAvailabilityStats> GetDataAvailabilityStatsAsync()
{
logger.LogInformation("Getting data availability stats");
var stats = await openCandRepository.GetDataAvailabilityAsync();
return stats;
}
public async Task<DatabaseTechStats> GetDatabaseTechStatsAsync()
{
logger.LogInformation("Getting database tech stats");
var stats = await openCandRepository.GetDatabaseTechStatsAsync();
stats.Tables = stats.Tables.OrderBy(t => t.Name).ToList();
stats.MaterializedViews = stats.MaterializedViews.OrderBy(mv => mv.Name).ToList();
return stats;
}
public async Task<CandidatoSearchResult> SearchCandidatosAsync(string query)
{
logger.LogInformation($"Searching candidatos with query: {query}");
return new CandidatoSearchResult()
{
Candidatos = await candidatoRepository.SearchCandidatosAsync(query) ?? new List<Candidato>()
};
}
public async Task<Guid?> GetRandomCandidato()
{
logger.LogInformation("Getting random candidato");
return await candidatoRepository.GetRandomCandidatoIdAsync();
}
public async Task<Candidato> GetCandidatoAsync(Guid idcandidato)
{
var result = await candidatoRepository.GetCandidatoAsync(idcandidato);
var eleicoes = await candidatoRepository.GetCandidatoMappingById(idcandidato);
var candidatoExt = await candidatoRepository.GetCandidatoExtById(idcandidato);
try
{
await candidatoRepository.IncreaseCandidatoPopularity(idcandidato);
}
catch (Exception ex)
{
logger.LogError(ex, $"Error increasing popularity for Candidato ID {idcandidato}");
}
if (result == null)
{
throw new KeyNotFoundException($"Candidato with ID {idcandidato} not found.");
}
if (eleicoes == null || eleicoes.Count == 0)
{
throw new KeyNotFoundException($"CandidatoMapping for ID {idcandidato} not found.");
}
if (candidatoExt == null)
{
throw new KeyNotFoundException($"CandidatoExt for ID {idcandidato} not found.");
}
foreach (var eleicao in eleicoes)
{
eleicao.Partido = await candidatoRepository.GetPartidoBySigla(eleicao.Sgpartido);
}
var lastEleicao = eleicoes.OrderByDescending(e => e.Ano).First();
result.FotoUrl = $"{fotoSettings.ApiBasePath}/foto_cand{lastEleicao.Ano}_{lastEleicao.SiglaUF}_div/F{lastEleicao.SiglaUF}{lastEleicao.SqCandidato}_div.jpg";
result.Eleicoes = eleicoes.OrderByDescending(e => e.Ano).ToList();
result.CandidatoExt = candidatoExt.OrderByDescending(ce => ce.Ano).ToList();
logger.LogDebug($"Found Candidato: {result.Nome}, ID: {result.IdCandidato}, CPF: {result.Cpf}, FotoUrl: {result.FotoUrl}");
return result;
}
public async Task<BemCandidatoResult> GetBemCandidatoById(Guid idcandidato)
{
var result = await bemCandidatoRepository.GetBemCandidatoAsync(idcandidato);
if (result == null)
{
result = new List<BemCandidato>();
}
logger.LogInformation($"Found {result.Count} bens for Candidato ID {idcandidato}");
return new BemCandidatoResult()
{
Bens = result.OrderByDescending(r => r.TipoBem).ThenByDescending(r => r.Valor).ToList()
};
}
public async Task<RedeSocialResult> GetCandidatoRedeSocialById(Guid idcandidato)
{
logger.LogInformation($"Getting redes sociais for Candidato ID {idcandidato}");
var result = await candidatoRepository.GetCandidatoRedeSocialById(idcandidato);
if (result == null)
{
result = new List<RedeSocial>();
}
logger.LogDebug($"Found {result.Count} redes sociais for Candidato ID {idcandidato}");
return new RedeSocialResult()
{
RedesSociais = result.OrderByDescending(r => r.Ano).ToList()
};
}
public async Task<CpfRevealResult> GetCandidatoCpfById(Guid idcandidato)
{
logger.LogInformation($"Getting CPF for Candidato ID {idcandidato}");
var result = await candidatoRepository.GetCandidatoCpfAsync(idcandidato);
if (result == null)
{
return new CpfRevealResult();
}
logger.LogDebug($"Found CPF {result} for Candidato ID {idcandidato}");
return new CpfRevealResult()
{
Cpf = result
};
}
public async Task<DespesasResult> GetDespesasByIdAndYear(Guid idcandidato)
{
logger.LogInformation($"Getting despesas for Candidato ID {idcandidato}");
var result = await despesaReceitaRepository.GetDespesasByCandidatoIdYearAsync(idcandidato);
if (result == null)
{
return new DespesasResult();
}
logger.LogDebug($"Found {result.Count} despesas for Candidato ID {idcandidato}");
return new DespesasResult()
{
Despesas = result.OrderByDescending(d => d.Ano).ThenByDescending(d => d.Valor).ToList()
};
}
public async Task<ReceitaResult> GetReceitasByIdAndYear(Guid idcandidato)
{
logger.LogInformation($"Getting receitas for Candidato ID {idcandidato}");
var result = await despesaReceitaRepository.GetReceitasByCandidatoIdYearAsync(idcandidato);
if (result == null)
{
return new ReceitaResult();
}
logger.LogDebug($"Found {result.Count} receitas for Candidato ID {idcandidato}");
return new ReceitaResult()
{
Receitas = result.OrderByDescending(d => d.Ano).ThenByDescending(d => d.Valor).ToList()
};
}
}
}