From c27334966309d5ed36b7562f930198c1b1c240eb Mon Sep 17 00:00:00 2001 From: Frederico Castro Date: Wed, 31 Dec 2025 03:12:43 -0300 Subject: [PATCH] =?UTF-8?q?fix:=20corrigir=20filtro=20Ativo/Inativo=20e=20?= =?UTF-8?q?c=C3=A1lculo=20de=20anos=20para=20consultores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filtro E_CONSULTOR: - Adicionar coluna E_CONSULTOR na tabela TB_RANKING_CONSULTOR - Filtrar apenas consultores ao selecionar Ativo/Inativo - Não-consultores não aparecem mais no filtro de inativos Correção de anos para inativos: - Calcular anos_consecutivos baseado no período histórico (não mais 0) - Calcular anos_atuacao usando data fim do período (não datetime.now()) --- backend/sql/schema_ranking.sql | 5 ++++- .../src/application/jobs/processar_ranking.py | 1 + backend/src/domain/entities/consultor.py | 3 ++- .../infrastructure/oracle/ranking_repository.py | 10 ++++++++-- backend/src/infrastructure/ranking_store.py | 7 ++++--- .../repositories/consultor_repository_impl.py | 17 ++++++++++++++--- backend/src/interface/api/routes.py | 2 +- 7 files changed, 34 insertions(+), 11 deletions(-) diff --git a/backend/sql/schema_ranking.sql b/backend/sql/schema_ranking.sql index 6168580..53d1551 100644 --- a/backend/sql/schema_ranking.sql +++ b/backend/sql/schema_ranking.sql @@ -14,17 +14,20 @@ CREATE TABLE TB_RANKING_CONSULTOR ( COMPONENTE_D NUMBER(10,2) DEFAULT 0, COMPONENTE_E NUMBER(10,2) DEFAULT 0, ATIVO CHAR(1) DEFAULT 'N', + E_CONSULTOR CHAR(1) DEFAULT 'N', ANOS_ATUACAO NUMBER(5,1) DEFAULT 0, DT_CALCULO TIMESTAMP DEFAULT CURRENT_TIMESTAMP, JSON_DETALHES CLOB, CONSTRAINT PK_RANKING_CONSULTOR PRIMARY KEY (ID_PESSOA), - CONSTRAINT CHK_ATIVO CHECK (ATIVO IN ('S', 'N')) + CONSTRAINT CHK_ATIVO CHECK (ATIVO IN ('S', 'N')), + CONSTRAINT CHK_E_CONSULTOR CHECK (E_CONSULTOR IN ('S', 'N')) ); -- Índices para performance CREATE INDEX IDX_RANKING_POSICAO ON TB_RANKING_CONSULTOR(POSICAO); CREATE INDEX IDX_RANKING_PONTUACAO ON TB_RANKING_CONSULTOR(PONTUACAO_TOTAL DESC); CREATE INDEX IDX_RANKING_ATIVO ON TB_RANKING_CONSULTOR(ATIVO); +CREATE INDEX IDX_RANKING_E_CONSULTOR ON TB_RANKING_CONSULTOR(E_CONSULTOR); CREATE INDEX IDX_RANKING_DT_CALCULO ON TB_RANKING_CONSULTOR(DT_CALCULO DESC); -- Procedure para atualizar posições após processamento diff --git a/backend/src/application/jobs/processar_ranking.py b/backend/src/application/jobs/processar_ranking.py index 21c17c0..a39f816 100644 --- a/backend/src/application/jobs/processar_ranking.py +++ b/backend/src/application/jobs/processar_ranking.py @@ -260,6 +260,7 @@ class ProcessarRankingJob: bloco_d=int(c.get("bloco_d", 0)), bloco_e=int(c.get("bloco_e", 0)), ativo=bool(c.get("ativo", False)), + e_consultor=c.get("consultoria") is not None, anos_atuacao=float(c.get("anos_atuacao", 0) or 0), detalhes=c, ) diff --git a/backend/src/domain/entities/consultor.py b/backend/src/domain/entities/consultor.py index 1a115e9..bf3e7aa 100644 --- a/backend/src/domain/entities/consultor.py +++ b/backend/src/domain/entities/consultor.py @@ -153,7 +153,8 @@ class Consultor: def anos_atuacao(self) -> float: if not self.consultoria or not self.consultoria.periodo.inicio: return 0.0 - dias = (datetime.now() - self.consultoria.periodo.inicio).days + fim = self.consultoria.periodo.fim or datetime.now() + dias = (fim - self.consultoria.periodo.inicio).days return round(dias / 365.25, 1) @property diff --git a/backend/src/infrastructure/oracle/ranking_repository.py b/backend/src/infrastructure/oracle/ranking_repository.py index 61051ce..16add72 100644 --- a/backend/src/infrastructure/oracle/ranking_repository.py +++ b/backend/src/infrastructure/oracle/ranking_repository.py @@ -25,11 +25,11 @@ class RankingOracleRepository: INSERT INTO TB_RANKING_CONSULTOR ( ID_PESSOA, NOME, PONTUACAO_TOTAL, COMPONENTE_A, COMPONENTE_B, COMPONENTE_C, COMPONENTE_D, COMPONENTE_E, - ATIVO, ANOS_ATUACAO, JSON_DETALHES, SELOS, DT_CALCULO + ATIVO, E_CONSULTOR, ANOS_ATUACAO, JSON_DETALHES, SELOS, DT_CALCULO ) VALUES ( :id_pessoa, :nome, :pontuacao_total, :componente_a, :componente_b, :componente_c, :componente_d, :componente_e, - :ativo, :anos_atuacao, :json_detalhes, :selos, CURRENT_TIMESTAMP + :ativo, :e_consultor, :anos_atuacao, :json_detalhes, :selos, CURRENT_TIMESTAMP ) """ @@ -38,6 +38,7 @@ class RankingOracleRepository: json_str = json.dumps(consultor, ensure_ascii=False) selos_set = extrair_selos_entry(consultor) selos_str = ",".join(sorted(selos_set)) if selos_set else None + e_consultor = consultor.get("consultoria") is not None batch_data.append({ "id_pessoa": int(consultor["id_pessoa"]), "nome": str(consultor.get("nome", ""))[:500], @@ -48,6 +49,7 @@ class RankingOracleRepository: "componente_d": int(consultor.get("bloco_d") or consultor.get("componente_d") or 0), "componente_e": int(consultor.get("bloco_e") or consultor.get("componente_e") or 0), "ativo": "S" if consultor.get("ativo") else "N", + "e_consultor": "S" if e_consultor else "N", "anos_atuacao": float(consultor.get("anos_atuacao") or 0), "json_detalhes": json_str, "selos": selos_str @@ -91,6 +93,7 @@ class RankingOracleRepository: } if filtro_ativo is not None: + where_clauses.append("E_CONSULTOR = 'S'") where_clauses.append("ATIVO = :ativo") params["ativo"] = "S" if filtro_ativo else "N" @@ -169,6 +172,7 @@ class RankingOracleRepository: params = {} if filtro_ativo is not None: + where_clauses.append("E_CONSULTOR = 'S'") where_clauses.append("ATIVO = :ativo") params["ativo"] = "S" if filtro_ativo else "N" @@ -410,6 +414,7 @@ class RankingOracleRepository: params = {} if filtro_ativo is not None: + where_clauses.append("E_CONSULTOR = 'S'") where_clauses.append("ATIVO = :ativo") params["ativo"] = "S" if filtro_ativo else "N" @@ -477,6 +482,7 @@ class RankingOracleRepository: params = {} if filtro_ativo is not None: + where_clauses.append("E_CONSULTOR = 'S'") where_clauses.append("ATIVO = :ativo") params["ativo"] = "S" if filtro_ativo else "N" diff --git a/backend/src/infrastructure/ranking_store.py b/backend/src/infrastructure/ranking_store.py index f560977..43ced59 100644 --- a/backend/src/infrastructure/ranking_store.py +++ b/backend/src/infrastructure/ranking_store.py @@ -161,6 +161,7 @@ class RankingEntry: bloco_d: int bloco_e: int ativo: bool + e_consultor: bool anos_atuacao: float detalhes: Dict[str, Any] @@ -192,7 +193,7 @@ class RankingStore: def total(self, filtro_ativo: Optional[bool] = None) -> int: if filtro_ativo is None: return len(self._entries) - return sum(1 for e in self._entries if e.ativo == filtro_ativo) + return sum(1 for e in self._entries if e.e_consultor and e.ativo == filtro_ativo) def get_page( self, @@ -209,7 +210,7 @@ class RankingStore: entries = self._entries if filtro_ativo is not None: - entries = [e for e in entries if e.ativo == filtro_ativo] + entries = [e for e in entries if e.e_consultor and e.ativo == filtro_ativo] if filtro_selos: selos_set = set(filtro_selos) @@ -234,7 +235,7 @@ class RankingStore: if filtro_ativo is None: entries = self._entries else: - entries = [e for e in self._entries if e.ativo == filtro_ativo] + entries = [e for e in self._entries if e.e_consultor and e.ativo == filtro_ativo] total = len(entries) return total, entries[offset : offset + limit] diff --git a/backend/src/infrastructure/repositories/consultor_repository_impl.py b/backend/src/infrastructure/repositories/consultor_repository_impl.py index 3d53945..c74e4d1 100644 --- a/backend/src/infrastructure/repositories/consultor_repository_impl.py +++ b/backend/src/infrastructure/repositories/consultor_repository_impl.py @@ -222,13 +222,24 @@ class ConsultorRepositoryImpl(ConsultorRepository): 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 + if periodo_ativo: + anos_consecutivos = periodo_ativo.anos_completos(datetime.now()) + elif mesclados: + anos_list = [p.anos_completos(p.fim or datetime.now()) for p in mesclados] + anos_consecutivos = max(anos_list) if anos_list else 0 + else: + anos_consecutivos = 0 retornos = max(0, len(mesclados) - 1) ativo = any(p.ativo for p in periodos) situacao_final = situacoes[-1] if situacoes else "N/A" - is_ativo = ativo or "atividade" in situacao_final.lower() or "ativo" in situacao_final.lower() - is_falecido = "falecido" in situacao_final.lower() + situacao_lower = situacao_final.lower() + is_ativo = ativo or ( + ("atividade" in situacao_lower or "ativo" in situacao_lower) + and "inatividade" not in situacao_lower + and "inativo" not in situacao_lower + ) + is_falecido = "falecido" in situacao_lower if is_falecido: codigo = "CONS_FALECIDO" diff --git a/backend/src/interface/api/routes.py b/backend/src/interface/api/routes.py index 91c2833..4ada429 100644 --- a/backend/src/interface/api/routes.py +++ b/backend/src/interface/api/routes.py @@ -222,7 +222,7 @@ async def ranking_paginado( total = oracle_repo.contar_total(filtro_ativo=ativo, filtro_selos=selos_lista) if total == 0: - if selos_lista: + if selos_lista or ativo is not None: return RankingPaginadoResponseSchema( total=0, page=page, size=size, total_pages=0, consultores=[] )