--- name: indicador-desempenho description: Guia de manutenção/extensão da ferramenta "Indicador de Desempenho" do Portal De Paula (Geradoc, portal_api/indicadores/, tela indicador-desempenho.html). Documenta o que ela substitui (apuração manual em planilha .ods do Fiscontábil), por que o escopo hoje é só esse departamento, e a limitação conhecida de resolução por gerente ao expandir pra outros departamentos. Usar ao investigar um valor de apuração, ao dar manutenção nos critérios/percentuais, ou ao planejar a expansão pra outro departamento além do Fisco/Contábil. --- # Indicador de Desempenho: origem, escopo e limitações conhecidas ## 0. O que este documento é Complemento de contexto de negócio pro `CLAUDE.md` (seção "Indicador de Desempenho (Geradoc)"), que já documenta a arquitetura técnica em detalhe (8 models, fórmula de composição, endpoints de ajuste em lote, layout do recibo em PDF). Ler os dois antes de mexer em cálculo de percentual ou em departamento, este arquivo foca no "por quê" e nas limitações que ainda não têm solução. ## 1. Origem: apuração manual em planilha quebrada A ferramenta substitui a apuração mensal do indicador de desempenho do Fiscontábil (departamentos Contábil/Fiscal do escritório), antes feita numa planilha `.ods` com fórmulas quebradas por anos de edição manual acumulada. O material de origem está versionado no próprio repositório, em `Portal/projects/Indicadores/`: - `FISCO CONTABIL 0726 OK.ods`: a planilha antiga (última versão "OK" antes da migração), fonte dos primeiros percentuais/critérios semeados via `seed_indicador_desempenho`. - `Honorários Por Cliente.xlsx` e `Serviços Tareffa.xlsx`: os dois relatórios que o RH sobe todo mês na tela ("Nova Apuração"), mesmo formato desde então. - `Modelo de Recibo.pdf`: referência visual original do recibo entregue a cada colaborador. `indicadores/recibo.py` reproduz o mesmo formato em `reportlab`. Se um valor calculado pela ferramenta parecer estranho pra uma competência antiga, comparar contra a planilha `.ods` antes de assumir que é bug, mas lembrar que a planilha tinha fórmulas comprovadamente quebradas, então "diferente da planilha" não é automaticamente "a ferramenta está errada". ## 2. Escopo v1: só Fisco/Contábil, mas a estrutura já é multi-departamento Só o Fisco/Contábil (papéis Balancete/Liberação Fiscal/Conciliação Financeira) tem critérios e percentuais cadastrados hoje, mas o modelo de dados (`IndicadorDepartamento`, `IndicadorDepartamentoGerente`, critérios/percentuais com FK pra departamento) já foi desenhado pra suportar outros departamentos desde a rodada em que isso foi introduzido, não é uma limitação de schema. Adicionar um departamento novo é: cadastrar o `IndicadorDepartamento` (Configurações → Departamentos), mapear os gerentes dele (`IndicadorDepartamentoGerente`), e cadastrar os critérios/percentuais próprios daquele departamento (RH decide os valores, não é herdado do Fisco/Contábil). ## 3. Limitação conhecida e sem solução hoje: resolução de departamento por gerente `IndicadorApuracaoColaborador.departamento` é resolvido **pelo gerente do colaborador** (`departamentos.carrega_mapa_gerentes()`, `{nome_gerente: departamento_id}`), não pelo colaborador individualmente. Isso quebra quando **um mesmo gerente supervisiona pessoas de departamentos diferentes**: caso real já confirmado com dados reais, "Elizangela de Paula Kuhn" supervisiona diretamente os líderes do Fisco/Contábil **e** Luciane Gonzaga, que deveria cair no departamento "Rocket". Como todos compartilham o mesmo gerente, mapear Elizangela para "Gerentes" classifica Luciane como "Gerentes" também, errado. Não existe mais um mecanismo de exceção por colaborador individual, o antigo `IndicadorSetorApelido` cobria exatamente esse tipo de caso e foi removido na migração pra departamentos (`0033` a `0035`). **Antes de expandir a ferramenta pra um segundo departamento de verdade**, decidir como resolver isso. As opções mais óbvias são: (a) reintroduzir uma exceção por nome de colaborador por cima da relação gerente/departamento, ou (b) resolver departamento por outro campo já existente na planilha Tareffa (se houver um mais granular que "gerente"). Não presumir qual das duas o usuário prefere sem perguntar, é uma decisão de produto, não só técnica. ## 4. Percentuais/critérios são cadastro editável, nunca hardcoded O primeiro histórico (`seed_indicador_desempenho`, idempotente) foi populado com os valores exatos da planilha antiga, mas com `vigente_desde` fixado em **01/01/2024 por falta de data documentada** na planilha de origem. Se o usuário informar a data real em que essas regras passaram a valer, corrigir esse seed (ou os registros já criados no banco, se o seed já rodou em produção) em vez de deixar a data placeholder implícita como se fosse a data real. ## 5. Robustez: bugs reais encontrados testando com dados de produção (43 colaboradores) Duas armadilhas já mordidas uma vez, que valem a pena verificar de novo em qualquer parser/campo novo desta ferramenta: - `openpyxl.load_workbook(..., read_only=True)` precisa de `.close()` explícito (`indicadores/leiaute.py`). Sem isso, o Windows mantém o arquivo de upload memory-mapped e bloqueia excluir a apuração depois (erro só aparece na hora de excluir, não na hora de processar, fácil de não notar em teste rápido). - Todo `DecimalField` que representa "um percentual de 0 a 100" precisa de `max_digits >= decimal_places + 3`, não `+ 2`. O valor exato `100` não cabe senão (`DataError: numeric field overflow`), erro que só aparece quando um colaborador de fato bate 100% em algum critério, não em qualquer teste com valores fracionários. ## 6. Correção deliberada no recibo: o banner sempre mostra o percentual medido, nunca o pago Quando `pct_individual` é ajustado manualmente pela Diretoria/RH (ex.: forçado para 100%), o banner "PERCENTUAL DO INDICADOR INDIVIDUAL" do PDF continua mostrando o percentual **efetivo/medido** (recalculado na hora via `composicao_individual()`), não o valor pago. Decisão explícita do usuário, pra o colaborador sempre ver o que de fato atingiu, com uma linha de detalhe separada mostrando o valor ajustado ao lado. Não "simplificar" isso pra mostrar só `pct_individual` puro no banner, perderia essa distinção intencional entre medido e pago.