feat(vinculos): adicionar vínculos de consultoria com IES e ordenação cronológica

- Adicionar entidades e DTOs para vínculos de consultoria (IES, período, situação)
- Extrair vínculos do Elasticsearch com datas e informações da IES
- Exibir vínculos no card do consultor com sigla e nome completo da IES
- Ordenar todas as listas do detalhe por data/ano decrescente (mais recente primeiro)
This commit is contained in:
Frederico Castro
2025-12-17 20:48:50 -03:00
parent 678be6170f
commit 99ce6e30d8
9 changed files with 167 additions and 7 deletions

View File

@@ -21,6 +21,20 @@ class CoordenacaoCapesDTO:
presidente: bool
@dataclass
class IESDTO:
id: str
nome: str
sigla: Optional[str] = None
@dataclass
class VinculoConsultoriaDTO:
periodo: PeriodoDTO
ies: Optional[IESDTO] = None
situacao: str = ""
@dataclass
class ConsultoriaDTO:
codigo: str
@@ -29,6 +43,11 @@ class ConsultoriaDTO:
areas: List[str]
anos_consecutivos: int
retornos: int
vinculos: List[VinculoConsultoriaDTO] = None
def __post_init__(self):
if self.vinculos is None:
self.vinculos = []
@dataclass

View File

@@ -131,7 +131,21 @@ class ProcessarRankingJob:
"fim": consultor.consultoria.periodo.fim.isoformat() if consultor.consultoria.periodo.fim else None,
"areas": consultor.consultoria.areas,
"anos_consecutivos": consultor.consultoria.anos_consecutivos,
"retornos": consultor.consultoria.retornos
"retornos": consultor.consultoria.retornos,
"vinculos": [
{
"inicio": v.periodo.inicio.isoformat() if v.periodo.inicio else None,
"fim": v.periodo.fim.isoformat() if v.periodo.fim else None,
"ativo": v.periodo.ativo,
"situacao": v.situacao,
"ies": {
"id": v.ies.id,
"nome": v.ies.nome,
"sigla": v.ies.sigla,
} if v.ies else None,
}
for v in consultor.consultoria.vinculos
],
} if consultor.consultoria else None,
"inscricoes": [
{

View File

@@ -8,6 +8,8 @@ from ..dtos.consultor_dto import (
PeriodoDTO,
CoordenacaoCapesDTO,
ConsultoriaDTO,
IESDTO,
VinculoConsultoriaDTO,
InscricaoDTO,
AvaliacaoComissaoDTO,
PremiacaoDTO,
@@ -91,6 +93,23 @@ class ObterRankingUseCase:
areas=consultor.consultoria.areas,
anos_consecutivos=consultor.consultoria.anos_consecutivos,
retornos=consultor.consultoria.retornos,
vinculos=[
VinculoConsultoriaDTO(
periodo=PeriodoDTO(
inicio=v.periodo.inicio.isoformat() if v.periodo.inicio else "",
fim=v.periodo.fim.isoformat() if v.periodo.fim else None,
ativo=v.periodo.ativo,
anos_decorridos=v.periodo.anos_decorridos,
),
ies=IESDTO(
id=v.ies.id,
nome=v.ies.nome,
sigla=v.ies.sigla,
) if v.ies else None,
situacao=v.situacao,
)
for v in consultor.consultoria.vinculos
],
) if consultor.consultoria else None,
inscricoes=[
InscricaoDTO(

View File

@@ -17,12 +17,27 @@ class CoordenacaoCapes:
presidente: bool = False
@dataclass
class IES:
id: str
nome: str
sigla: Optional[str] = None
@dataclass
class VinculoConsultoria:
periodo: Periodo
ies: Optional[IES] = None
situacao: str = ""
@dataclass
class Consultoria:
codigo: str
situacao: str
periodo: Periodo
periodos: List[Periodo] = field(default_factory=list)
vinculos: List[VinculoConsultoria] = field(default_factory=list)
areas: List[str] = field(default_factory=list)
anos_consecutivos: int = 0
retornos: int = 0

View File

@@ -8,6 +8,8 @@ from ...domain.entities.consultor import (
Consultor,
CoordenacaoCapes,
Consultoria,
IES,
VinculoConsultoria,
Inscricao,
AvaliacaoComissao,
Premiacao,
@@ -140,6 +142,7 @@ class ConsultorRepositoryImpl(ConsultorRepository):
return None
periodos: List[Periodo] = []
vinculos: List[VinculoConsultoria] = []
situacoes: List[str] = []
areas: List[str] = []
@@ -162,9 +165,25 @@ class ConsultorRepositoryImpl(ConsultorRepository):
if inicio and fim and fim < inicio:
fim = None
ies_data = dc.get("ies", {}) or {}
ies = None
if ies_data and (ies_data.get("id") or ies_data.get("nome")):
ies = IES(
id=str(ies_data.get("id", "")),
nome=ies_data.get("nome", ""),
sigla=ies_data.get("sigla"),
)
if inicio:
try:
periodos.append(Periodo(inicio=inicio, fim=fim))
periodo = Periodo(inicio=inicio, fim=fim)
periodos.append(periodo)
vinculos.append(VinculoConsultoria(
periodo=periodo,
ies=ies,
situacao=situacao or "",
))
except ValueError:
continue
@@ -176,6 +195,8 @@ class ConsultorRepositoryImpl(ConsultorRepository):
if not periodos:
return None
vinculos.sort(key=lambda v: v.periodo.inicio, reverse=True)
mesclados = mesclar_periodos(periodos)
periodo_ativo = next((p for p in mesclados if p.ativo), None)
anos_consecutivos = periodo_ativo.anos_completos(datetime.now()) if periodo_ativo else 0
@@ -205,6 +226,7 @@ class ConsultorRepositoryImpl(ConsultorRepository):
situacao=situacao_final,
periodo=Periodo(inicio=primeiro_evento, fim=fim_final),
periodos=mesclados,
vinculos=vinculos,
areas=areas,
anos_consecutivos=anos_consecutivos,
retornos=retornos,

View File

@@ -9,6 +9,18 @@ class PeriodoSchema(BaseModel):
anos_decorridos: float
class IESSchema(BaseModel):
id: str
nome: str
sigla: Optional[str] = None
class VinculoConsultoriaSchema(BaseModel):
periodo: PeriodoSchema
ies: Optional[IESSchema] = None
situacao: str = ""
class CoordenacaoCapesSchema(BaseModel):
codigo: str
tipo: str
@@ -23,6 +35,7 @@ class ConsultoriaSchema(BaseModel):
codigo: str
situacao: str
periodo: PeriodoSchema
vinculos: List[VinculoConsultoriaSchema] = []
areas: List[str]
anos_consecutivos: int
retornos: int