feat: implementar novos critérios de pontuação da planilha atualizada
- Adicionar critérios diferenciados por papel (autor vs orientador) - Implementar INSC_INST_AUTOR, PREMIACAO_GP_AUTOR, PREMIACAO_AUTOR, MENCAO_AUTOR - Adicionar bônus de recorrência para inscrições, eventos e projetos - Corrigir lógica de bônus de consultoria (continuidade e retorno) - Ajustar extração de selos no frontend para novos códigos - Adicionar BOL_BPQ_NIVEL para bolsas sem nível especificado - Refinar cálculo de pontuação com novos tetos e multiplicadores
This commit is contained in:
@@ -73,9 +73,7 @@ class ProcessarRankingJob:
|
||||
for doc in docs:
|
||||
try:
|
||||
consultor = await self.consultor_repo._construir_consultor(doc)
|
||||
|
||||
self._consultores.append(self._gerar_json_detalhes(consultor))
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
logger.warning(f"Erro ao processar consultor {doc.get('id')}: {e}")
|
||||
|
||||
@@ -90,19 +90,19 @@ class CalculadorPontuacao:
|
||||
|
||||
bonus = 0
|
||||
|
||||
# Bônus de continuidade (escalonado, não cumulativo) - apenas CONS_ATIVO
|
||||
# Spec: 8+ anos = 20 pts (era 15, corrigido conforme especificação)
|
||||
if codigo == "CONS_ATIVO":
|
||||
if consultoria.anos_consecutivos >= 8:
|
||||
bonus += 20
|
||||
elif consultoria.anos_consecutivos >= 5:
|
||||
if consultoria.periodo.ativo and criterio.bonus_atualidade:
|
||||
bonus += criterio.bonus_atualidade
|
||||
|
||||
if consultoria.anos_consecutivos >= 8 and criterio.bonus_continuidade_8anos:
|
||||
bonus += criterio.bonus_continuidade_8anos
|
||||
elif codigo == "CONS_ATIVO":
|
||||
if consultoria.anos_consecutivos >= 5:
|
||||
bonus += 10
|
||||
elif consultoria.anos_consecutivos >= 3:
|
||||
bonus += 5
|
||||
|
||||
# Bônus de retorno (uma vez) - apenas CONS_ATIVO
|
||||
if consultoria.retornos > 0 and criterio.bonus_retorno:
|
||||
bonus += criterio.bonus_retorno
|
||||
if consultoria.retornos > 0 and criterio.bonus_retorno:
|
||||
bonus += criterio.bonus_retorno
|
||||
|
||||
total_bruto = base + tempo + bonus
|
||||
total = min(total_bruto, criterio.teto) if criterio.teto > 0 else total_bruto
|
||||
@@ -185,7 +185,13 @@ class CalculadorPontuacao:
|
||||
if criterio.bonus_recorrencia_anual > 0:
|
||||
anos_distintos = len(dados["anos"])
|
||||
bonus_recorrencia = anos_distintos * criterio.bonus_recorrencia_anual
|
||||
bonus = min(bonus_recorrencia, criterio.teto_recorrencia)
|
||||
bonus += min(bonus_recorrencia, criterio.teto_recorrencia)
|
||||
|
||||
if criterio.bonus_recorrencia_participacao > 0:
|
||||
bonus_participacao = dados["qtd"] * criterio.bonus_recorrencia_participacao
|
||||
if criterio.teto_recorrencia_participacao > 0:
|
||||
bonus_participacao = min(bonus_participacao, criterio.teto_recorrencia_participacao)
|
||||
bonus += bonus_participacao
|
||||
|
||||
total_bruto = base_total + bonus
|
||||
if criterio.teto > 0:
|
||||
|
||||
@@ -31,6 +31,8 @@ class CriterioPontuacao:
|
||||
bonus_continuidade_8anos: int = 0
|
||||
bonus_recorrencia_anual: int = 0
|
||||
teto_recorrencia: int = 0
|
||||
bonus_recorrencia_participacao: int = 0
|
||||
teto_recorrencia_participacao: int = 0
|
||||
|
||||
|
||||
CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
@@ -101,6 +103,7 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
pontua_tempo=True,
|
||||
multiplicador_tempo=5,
|
||||
teto_tempo=50,
|
||||
bonus_atualidade=20,
|
||||
bonus_retorno=15,
|
||||
bonus_continuidade_8anos=20,
|
||||
),
|
||||
@@ -113,6 +116,7 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
pontua_tempo=True,
|
||||
multiplicador_tempo=5,
|
||||
teto_tempo=50,
|
||||
bonus_retorno=20,
|
||||
bonus_continuidade_8anos=20,
|
||||
),
|
||||
"CONS_FALECIDO": CriterioPontuacao(
|
||||
@@ -132,6 +136,17 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
tipo=TipoAtuacao.FUNCAO,
|
||||
base=10,
|
||||
teto=20,
|
||||
bonus_recorrencia_participacao=2,
|
||||
teto_recorrencia_participacao=10,
|
||||
),
|
||||
"INSC_INST_AUTOR": CriterioPontuacao(
|
||||
codigo="INSC_INST_AUTOR",
|
||||
bloco=Bloco.D,
|
||||
tipo=TipoAtuacao.FUNCAO,
|
||||
base=20,
|
||||
teto=50,
|
||||
bonus_recorrencia_participacao=5,
|
||||
teto_recorrencia_participacao=10,
|
||||
),
|
||||
"INSC_INST": CriterioPontuacao(
|
||||
codigo="INSC_INST",
|
||||
@@ -204,6 +219,13 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
base=50,
|
||||
teto=100,
|
||||
),
|
||||
"BOL_BPQ_NIVEL": CriterioPontuacao(
|
||||
codigo="BOL_BPQ_NIVEL",
|
||||
bloco=Bloco.D,
|
||||
tipo=TipoAtuacao.COMPETENCIA_RECONHECIMENTO,
|
||||
base=30,
|
||||
teto=60,
|
||||
),
|
||||
"PREMIACAO": CriterioPontuacao(
|
||||
codigo="PREMIACAO",
|
||||
bloco=Bloco.D,
|
||||
@@ -218,6 +240,20 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
base=50,
|
||||
teto=60,
|
||||
),
|
||||
"PREMIACAO_GP_AUTOR": CriterioPontuacao(
|
||||
codigo="PREMIACAO_GP_AUTOR",
|
||||
bloco=Bloco.D,
|
||||
tipo=TipoAtuacao.COMPETENCIA_RECONHECIMENTO,
|
||||
base=100,
|
||||
teto=300,
|
||||
),
|
||||
"PREMIACAO_AUTOR": CriterioPontuacao(
|
||||
codigo="PREMIACAO_AUTOR",
|
||||
bloco=Bloco.D,
|
||||
tipo=TipoAtuacao.COMPETENCIA_RECONHECIMENTO,
|
||||
base=50,
|
||||
teto=150,
|
||||
),
|
||||
"MENCAO": CriterioPontuacao(
|
||||
codigo="MENCAO",
|
||||
bloco=Bloco.D,
|
||||
@@ -225,12 +261,21 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
base=30,
|
||||
teto=30,
|
||||
),
|
||||
"MENCAO_AUTOR": CriterioPontuacao(
|
||||
codigo="MENCAO_AUTOR",
|
||||
bloco=Bloco.D,
|
||||
tipo=TipoAtuacao.COMPETENCIA_RECONHECIMENTO,
|
||||
base=30,
|
||||
teto=90,
|
||||
),
|
||||
"EVENTO": CriterioPontuacao(
|
||||
codigo="EVENTO",
|
||||
bloco=Bloco.D,
|
||||
tipo=TipoAtuacao.PARTICIPACAO,
|
||||
base=1,
|
||||
teto=5,
|
||||
bonus_recorrencia_participacao=1,
|
||||
teto_recorrencia_participacao=10,
|
||||
),
|
||||
"PROJ": CriterioPontuacao(
|
||||
codigo="PROJ",
|
||||
@@ -238,6 +283,8 @@ CRITERIOS: Dict[str, CriterioPontuacao] = {
|
||||
tipo=TipoAtuacao.PARTICIPACAO,
|
||||
base=10,
|
||||
teto=40,
|
||||
bonus_recorrencia_participacao=2,
|
||||
teto_recorrencia_participacao=10,
|
||||
),
|
||||
"ORIENT_POS_DOC": CriterioPontuacao(
|
||||
codigo="ORIENT_POS_DOC",
|
||||
|
||||
@@ -51,6 +51,15 @@ def extrair_selos_entry(detalhes: Dict[str, Any]) -> Set[str]:
|
||||
tipo_prem = "PREMIO"
|
||||
elif codigo == "MENCAO":
|
||||
tipo_prem = "MENCAO"
|
||||
elif codigo == "PREMIACAO_GP_AUTOR":
|
||||
selos.add("AUTOR_GP")
|
||||
continue
|
||||
elif codigo == "PREMIACAO_AUTOR":
|
||||
selos.add("AUTOR_PREMIO")
|
||||
continue
|
||||
elif codigo == "MENCAO_AUTOR":
|
||||
selos.add("AUTOR_MENCAO")
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ class ConsultorRepositoryImpl(ConsultorRepository):
|
||||
ano = inicio.year if inicio else datetime.now().year
|
||||
|
||||
is_institucional = "coordenador" in tipo_part.lower() or "ppg" in tipo_part.lower()
|
||||
codigo = "INSC_INST" if is_institucional else "INSC_AUTOR"
|
||||
codigo = "INSC_INST_AUTOR" if is_institucional else "INSC_AUTOR"
|
||||
|
||||
inscricoes.append(Inscricao(
|
||||
codigo=codigo,
|
||||
@@ -330,12 +330,23 @@ class ConsultorRepositoryImpl(ConsultorRepository):
|
||||
nome_lower = str(nome_premio).lower()
|
||||
tipo_norm = self._inferir_premiacao_tipo(f"{tipo_lower} {nome_lower}")
|
||||
|
||||
if tipo_norm == "GP":
|
||||
codigo = "PREMIACAO"
|
||||
elif tipo_norm == "MENCAO":
|
||||
codigo = "MENCAO"
|
||||
papel_lower = str(papel or "").lower()
|
||||
is_autor = "autor" in papel_lower
|
||||
|
||||
if is_autor:
|
||||
if tipo_norm == "GP":
|
||||
codigo = "PREMIACAO_GP_AUTOR"
|
||||
elif tipo_norm == "MENCAO":
|
||||
codigo = "MENCAO_AUTOR"
|
||||
else:
|
||||
codigo = "PREMIACAO_AUTOR"
|
||||
else:
|
||||
codigo = "PREMIACAO_GP"
|
||||
if tipo_norm == "GP":
|
||||
codigo = "PREMIACAO"
|
||||
elif tipo_norm == "MENCAO":
|
||||
codigo = "MENCAO"
|
||||
else:
|
||||
codigo = "PREMIACAO_GP"
|
||||
|
||||
premiacoes.append(Premiacao(
|
||||
codigo=codigo,
|
||||
@@ -358,7 +369,9 @@ class ConsultorRepositoryImpl(ConsultorRepository):
|
||||
area = dados.get("areaConhecimento", "") or ""
|
||||
|
||||
nivel_lower = nivel.lower()
|
||||
if "1d" in nivel_lower or "2" in nivel_lower:
|
||||
if not nivel_lower:
|
||||
codigo = "BOL_BPQ_NIVEL"
|
||||
elif "1d" in nivel_lower or "2" in nivel_lower:
|
||||
codigo = "BOL_BPQ_INT"
|
||||
else:
|
||||
codigo = "BOL_BPQ_SUP"
|
||||
|
||||
Reference in New Issue
Block a user