from datetime import datetime from dateutil.relativedelta import relativedelta import pytest from src.domain.services.calculador_pontuacao import CalculadorPontuacao from src.domain.value_objects.criterios_pontuacao import CRITERIOS from src.domain.value_objects.periodo import Periodo from src.domain.entities.consultor import ( Consultoria, CoordenacaoCapes, Inscricao, AvaliacaoComissao, Participacao, ) PDF_BASE_TETO = { "CA": (200, 450), "CAJ": (150, 370), "CAJ_MP": (120, 315), "CAM": (100, 280), "PPG_COORD": (0, 0), "CONS_ATIVO": (150, 230), "CONS_HIST": (100, 230), "CONS_FALECIDO": (100, 230), "INSC_AUTOR": (10, 20), "INSC_INST_AUTOR": (20, 50), "AVAL_COMIS_PREMIO": (30, 60), "AVAL_COMIS_GP": (40, 80), "COORD_COMIS_PREMIO": (40, 100), "COORD_COMIS_GP": (50, 120), "BOL_BPQ_NIVEL": (30, 60), "PREMIACAO_GP_AUTOR": (100, 300), "PREMIACAO_AUTOR": (50, 150), "MENCAO_AUTOR": (30, 90), "EVENTO": (1, 5), "PROJ": (10, 30), "IDIOMA_BILINGUE": (0, 0), "IDIOMA_MULTILINGUE": (0, 0), "TITULACAO_MESTRE": (0, 0), "TITULACAO_DOUTOR": (0, 0), "TITULACAO_POS_DOUTOR": (0, 0), "ORIENT_POS_DOC": (0, 0), "ORIENT_POS_DOC_PREM": (0, 0), "ORIENT_TESE": (0, 0), "ORIENT_TESE_PREM": (0, 0), "ORIENT_DISS": (0, 0), "ORIENT_DISS_PREM": (0, 0), "CO_ORIENT_POS_DOC": (0, 0), "CO_ORIENT_POS_DOC_PREM": (0, 0), "CO_ORIENT_TESE": (0, 0), "CO_ORIENT_TESE_PREM": (0, 0), "CO_ORIENT_DISS": (0, 0), "CO_ORIENT_DISS_PREM": (0, 0), "MB_BANCA_POS_DOC": (0, 0), "MB_BANCA_POS_DOC_PREM": (0, 0), "MB_BANCA_TESE": (0, 0), "MB_BANCA_TESE_PREM": (0, 0), "MB_BANCA_DISS": (0, 0), "MB_BANCA_DISS_PREM": (0, 0), } PDF_TEMPO = { "CA": (10, 100), "CAJ": (8, 80), "CAJ_MP": (6, 60), "CAM": (5, 50), "PPG_COORD": (0, 0), "CONS_ATIVO": (5, 50), "CONS_HIST": (5, 50), "CONS_FALECIDO": (5, 50), } PDF_BONUS = { "CA": {"atualidade": 30, "retorno": 20}, "CAJ": {"atualidade": 20, "retorno": 15}, "CAJ_MP": {"atualidade": 15, "retorno": 10}, "CAM": {"atualidade": 20, "retorno": 10}, "PPG_COORD": {"atualidade": 15, "retorno": 10, "continuidade": 15}, "CONS_ATIVO": {"atualidade": 20, "retorno": 15, "continuidade": 20}, "CONS_HIST": {"retorno": 20, "continuidade": 20}, "CONS_FALECIDO": {"continuidade": 20}, } PDF_RECORRENCIA = { "INSC_AUTOR": {"por_participacao": 2, "teto_participacao": 10}, "INSC_INST_AUTOR": {"por_participacao": 5, "teto_participacao": 10}, "AVAL_COMIS_PREMIO": {"por_ano": 2, "teto_ano": 15}, "AVAL_COMIS_GP": {"por_ano": 3, "teto_ano": 20}, "COORD_COMIS_PREMIO": {"por_ano": 4, "teto_ano": 20}, "COORD_COMIS_GP": {"por_ano": 6, "teto_ano": 20}, "EVENTO": {"por_participacao": 1, "teto_participacao": 10}, "PROJ": {"por_participacao": 2, "teto_participacao": 10}, } def periodo_anos(anos: int, ativo: bool = False) -> Periodo: inicio = datetime.now() - relativedelta(years=anos) fim = None if ativo else datetime.now() return Periodo(inicio=inicio, fim=fim) @pytest.mark.parametrize("codigo,base_teto", PDF_BASE_TETO.items()) def test_pdf_base_teto(codigo, base_teto): criterio = CRITERIOS.get(codigo) assert criterio is not None base, teto = base_teto assert criterio.base == base assert criterio.teto == teto def test_pdf_criterios_cobrem_43_codigos(): assert set(CRITERIOS.keys()) == set(PDF_BASE_TETO.keys()) assert len(CRITERIOS) == 43 @pytest.mark.parametrize("codigo,tempo", PDF_TEMPO.items()) def test_pdf_regras_tempo(codigo, tempo): criterio = CRITERIOS[codigo] multiplicador, teto_tempo = tempo assert criterio.pontua_tempo is True assert criterio.multiplicador_tempo == multiplicador assert criterio.teto_tempo == teto_tempo @pytest.mark.parametrize("codigo", sorted(set(PDF_BASE_TETO) - set(PDF_TEMPO))) def test_pdf_codigos_sem_tempo(codigo): criterio = CRITERIOS[codigo] assert criterio.pontua_tempo is False assert criterio.multiplicador_tempo == 0 assert criterio.teto_tempo == 0 @pytest.mark.parametrize("codigo,bonus", PDF_BONUS.items()) def test_pdf_bonus_configurados(codigo, bonus): criterio = CRITERIOS[codigo] assert criterio.bonus_atualidade == bonus.get("atualidade", 0) assert criterio.bonus_retorno == bonus.get("retorno", 0) assert criterio.bonus_continuidade_8anos == bonus.get("continuidade", 0) @pytest.mark.parametrize("codigo,rec", PDF_RECORRENCIA.items()) def test_pdf_regras_recorrencia(codigo, rec): criterio = CRITERIOS[codigo] assert criterio.bonus_recorrencia_anual == rec.get("por_ano", 0) assert criterio.teto_recorrencia == rec.get("teto_ano", 0) assert criterio.bonus_recorrencia_participacao == rec.get("por_participacao", 0) assert criterio.teto_recorrencia_participacao == rec.get("teto_participacao", 0) def test_calculo_tempo_e_bonus_ca(): periodo_historico = Periodo( inicio=datetime.now() - relativedelta(years=12), fim=datetime.now() - relativedelta(years=2), ) periodo_ativo = periodo_anos(2, ativo=True) coords = [ CoordenacaoCapes( codigo="CA", tipo="Coordenador de Area", area_avaliacao="AREA", periodo=periodo_historico, ), CoordenacaoCapes( codigo="CA", tipo="Coordenador de Area", area_avaliacao="AREA", periodo=periodo_ativo, ), ] resultado = CalculadorPontuacao.calcular_bloco_a(coords) atuacao = resultado.atuacoes[0] assert atuacao.tempo == 100 assert atuacao.bonus == 50 def test_calculo_bonus_consultoria_completo(): consultoria = Consultoria( codigo="CONS_ATIVO", situacao="Ativo", periodo=periodo_anos(9, ativo=True), periodos=[periodo_anos(9, ativo=True)], anos_consecutivos=9, retornos=1, ) resultado = CalculadorPontuacao.calcular_bloco_b(consultoria) atuacao = resultado.atuacoes[0] assert atuacao.bonus == 55 def test_calculo_recorrencia_inscricao_autor_bonus(): inscricoes = [ Inscricao(codigo="INSC_AUTOR", tipo="Autor", premio="PCT", ano=2020), Inscricao(codigo="INSC_AUTOR", tipo="Autor", premio="PCT", ano=2021), Inscricao(codigo="INSC_AUTOR", tipo="Autor", premio="PCT", ano=2022), Inscricao(codigo="INSC_AUTOR", tipo="Autor", premio="PCT", ano=2023), Inscricao(codigo="INSC_AUTOR", tipo="Autor", premio="PCT", ano=2024), ] resultado = CalculadorPontuacao.calcular_bloco_c(inscricoes, [], [], [], []) atuacao = next(a for a in resultado.atuacoes if a.codigo == "INSC_AUTOR") assert atuacao.bonus == 10 def test_calculo_recorrencia_avaliacao_gp_bonus(): avaliacoes = [ AvaliacaoComissao(codigo="AVAL_COMIS_GP", tipo="Membro", premio="GP", ano=2021), AvaliacaoComissao(codigo="AVAL_COMIS_GP", tipo="Membro", premio="GP", ano=2022), AvaliacaoComissao(codigo="AVAL_COMIS_GP", tipo="Membro", premio="GP", ano=2023), ] resultado = CalculadorPontuacao.calcular_bloco_c([], avaliacoes, [], [], []) atuacao = next(a for a in resultado.atuacoes if a.codigo == "AVAL_COMIS_GP") assert atuacao.bonus == 9 def test_calculo_recorrencia_evento_bonus(): eventos = [ Participacao(codigo="EVENTO", tipo="Evento", ano=2020), Participacao(codigo="EVENTO", tipo="Evento", ano=2021), Participacao(codigo="EVENTO", tipo="Evento", ano=2022), Participacao(codigo="EVENTO", tipo="Evento", ano=2023), Participacao(codigo="EVENTO", tipo="Evento", ano=2024), Participacao(codigo="EVENTO", tipo="Evento", ano=2025), Participacao(codigo="EVENTO", tipo="Evento", ano=2026), Participacao(codigo="EVENTO", tipo="Evento", ano=2027), Participacao(codigo="EVENTO", tipo="Evento", ano=2028), Participacao(codigo="EVENTO", tipo="Evento", ano=2029), Participacao(codigo="EVENTO", tipo="Evento", ano=2030), ] resultado = CalculadorPontuacao.calcular_bloco_d([], eventos) atuacao = next(a for a in resultado.atuacoes if a.codigo == "EVENTO") assert atuacao.bonus == 10