Commit inicial do Portal De Paula

This commit is contained in:
Gabriel 2026-08-18 10:57:39 -03:00
commit 3a6c3e1815
221 changed files with 32889 additions and 0 deletions

50
.gitignore vendored Normal file
View File

@ -0,0 +1,50 @@
# Ambiente virtual
.venv/
venv/
env/
# Variáveis de ambiente / segredos
.env
.env.*
!.env.example
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
# Django
staticfiles/
db.sqlite3
db.sqlite3-journal
*.log
local_settings.py
# Distribuição / empacotamento
build/
dist/
*.egg-info/
.eggs/
# Ferramentas de teste/cobertura
.coverage
.coverage.*
htmlcov/
.pytest_cache/
.tox/
# Editores / IDEs
.vscode/
.idea/
*.swp
*.swo
# Sistema operacional
.DS_Store
Thumbs.db
desktop.ini
# Configuração local do Claude Code
.claude/settings.local.json

581
CLAUDE.md Normal file
View File

@ -0,0 +1,581 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Contexto do projeto
Portal interno da De Paula Contadores ("Portal De Paula"). `Portal/` **é** o próprio projeto Django — **Python 3.13 + Django 6.0 + Django REST Framework + PostgreSQL 14** — organizado no padrão convencional de um projeto Django (`manage.py` na raiz, app `portal_api/`, `templates/`, `static/`), servindo tanto a API (`/api/...`) quanto o frontend HTML/CSS/JS (mesma origem — ver "Arquitetura" abaixo).
Até uma rodada anterior, todo o estado (sessão, usuários, perfis de acesso, favoritos, widgets, compromissos) vivia no `localStorage` do navegador — não havia backend. Isso mudou: o usuário decidiu a stack real e pediu a migração completa desses dados para o banco. Ver `plano.md` para o histórico de decisões rodada a rodada; consultar antes de mudar algo que pareça uma limitação (ex.: ausência de teste automatizado, remoção do calendário interno antigo) sem confirmar se foi decisão deliberada.
**O que continua só no `localStorage`**: apenas a preferência de tema (claro/escuro e cor do tema) — é preferência de navegador, não dado de negócio, e ficou fora do escopo da migração por decisão explícita do usuário.
## Como rodar / testar localmente
### Backend (obrigatório para qualquer teste agora — o frontend não funciona mais sozinho via `file://`/`http.server`)
```
cd Portal
python -m venv .venv
.venv\Scripts\activate # Windows
pip install -r requirements.txt
```
Configurar as variáveis de ambiente do Postgres 14 antes de migrar — `config/settings.py` chama `load_dotenv(BASE_DIR / ".env")` e lê `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT` (o arquivo `.env` já existe na raiz de `Portal/`):
```
python manage.py makemigrations portal_api
python manage.py migrate
python manage.py seed_portal # recria os 8 perfis + usuários gabriel/bruno
python manage.py runserver
```
Abrir `http://localhost:8000/` — o Django serve `index.html` e as demais páginas do frontend diretamente (ver `config/urls.py`), então **não há mais um segundo servidor** (`python -m http.server`) para o frontend.Vamos desenvolver outra
Contas de demonstração (criadas por `seed_portal`, senha via `set_password` do Django — não é mais texto puro):
- `gabriel` / `gabriel` — perfil "Integração e Inovação" (código 8), o único com `gerencia_permissoes=True` (acesso total + gerencia Perfis de Acesso/Usuários) e o único com os `*-editar` de `links-ferramentas` (cartões e Acessos Gerais) e de `ramais` `True` (único perfil que pode reordenar/incluir/remover cartões em Links & Ferramentas, criar/editar seções e acessos em Acessos Gerais, e adicionar/editar ramal/criar ausência em Ramais, até que outro perfil seja liberado em Perfis de Acesso — ver "Modelo de permissões" abaixo).
- `bruno` / `bruno` — sem perfil vinculado, usado para testar o estado "sem acesso".
Não há suíte de testes, lint ou build configurados neste projeto.
### Ambiente de desenvolvimento assistido
O `.venv` do projeto já tem Python 3.13 + Django 6.0 + DRF + psycopg + python-dotenv + Pillow + nh3 + reportlab + openpyxl + holidays instalados, e há um Postgres local acessível via `.env` — dá pra rodar `makemigrations`/`migrate`/`seed_portal`/`runserver` normalmente por aqui usando `.venv\Scripts\python.exe manage.py ...` (ou ativando o venv primeiro). Isso deixou de ser uma limitação a partir da rodada em que o ambiente ganhou essas ferramentas (ver `plano.md`) — não assumir mais que só é possível revisar o backend estaticamente.
## Arquitetura
### Estrutura de pastas (padrão Django)
```
Portal/
├── manage.py
├── requirements.txt
├── .env
├── config/ # settings.py, urls.py, wsgi.py, asgi.py — pacote de configuração do projeto
├── portal_api/ # único app Django (models, serializers, views, admin, migrations, seed)
├── templates/ # as 8 páginas HTML (TEMPLATES[0]["DIRS"] em settings.py aponta pra cá)
├── static/ # css/, js/, img/ — STATICFILES_DIRS em settings.py aponta pra cá
├── media/ # upload de usuário (hoje só ícones de LinkFerramenta) — MEDIA_ROOT em settings.py
├── CLAUDE.md
└── plano.md
```
### Logos em `static/img/`
`static/img/` tem três variantes do logo "D De Paula Contadores" (D em degradê dourado/marrom + texto), todas PNG com fundo transparente:
- `logo.png` — original, texto **preto**. Serve como fonte pra gerar as outras variantes e também é usada diretamente em `index.html` (login) quando `data-theme="light"` — o card do login usa `--bg-surface` (claro nesse tema), e o texto branco de `logo-branco.png` ficava ilegível contra ele.
- `logo-branco.png` — usada em `index.html` no login quando `data-theme="dark"` (default) e sempre no `sidebar__brand` dos 5 shells (a sidebar usa fundo frozen sempre escuro, independente do tema — ver "Sidebar" em `layout.css` — então não precisa alternar) — mesmo D colorido de `logo.png`, mas com o texto recolorido pra branco. Gerada programaticamente a partir de `logo.png` (script Python com Pillow: qualquer pixel opaco quase-neutro/escuro — `max(r,g,b) < 70` e `spread(r,g,b) < 12` — virou branco; o D nunca entra nesse filtro porque mesmo na sombra mais escura do degradê ele mantém um matiz quente nitidamente não-neutro). Se o logo oficial mudar, regerar `logo-branco.png` a partir do novo `logo.png` com o mesmo filtro, não editar à mão.
- A troca da logo do login por tema é feita em `theme.js` (`pidSyncLoginLogo()`): o `<img id="login-logo">` de `index.html` carrega os dois caminhos resolvidos por `{% static %}` em `data-logo-dark`/`data-logo-light`, e o JS só troca o `src` conforme `data-theme` atual — chamado no load e no evento `pid:theme-changed`.
- `logo-mono.png` — versão totalmente monocromática (D **e** texto em branco/cinza claro). Não usada em nenhum template hoje; existe como variante alternativa (útil se algum dia precisar de um logo "chapado" sem o dourado do D).
- `favicon.png` — só o D (sem o texto "De Paula Contadores"), quadrado, 192×192, usado como ícone da aba do navegador (`<link rel="icon" type="image/png">` no `<head>` das 7 páginas). Gerado a partir de `logo.png` com o mesmo filtro de `logo-branco.png` (pixel opaco quase-neutro/escuro — `max(r,g,b) < 70` e `spread(r,g,b) < 12` — é texto, não o D), mas em vez de recolorir esses pixels pra branco, eles são apagados (`alpha = 0`); o resultado é recortado pelo bounding box do que sobrou opaco e centralizado num canvas quadrado transparente (o D é mais alto que largo). Se o logo oficial mudar, regerar a partir do novo `logo.png` com o mesmo processo, não editar à mão.
Tamanho: `.sidebar__logo` é `width: 200px; height: auto` (era 56×56 fixo, esmagava o logo — a arte é bem mais larga que alta, ~1.41:1 — e ficava pequena demais); encolhe pra `44px` quando a sidebar colapsa (desktop `.is-collapsed` e o breakpoint mobile), senão o logo vaza da faixa de 76px.
### Backend serve o frontend (mesma origem)
`config/urls.py` registra `path("api/", include("portal_api.urls"))` e, para cada página HTML do frontend (`index.html`, `portal.html`, `perfis-acesso.html`, `usuarios.html`, `calendario-individual.html`, `links-ferramentas.html`, `acessos-gerais.html`, `ramais.html`), uma rota `TemplateView` que resolve o arquivo em `templates/`. Os estáticos (`static/css`, `static/js`, `static/img`) são servidos por `django.contrib.staticfiles` automaticamente em `DEBUG` (via `STATICFILES_DIRS`) — não há mais nenhum `re_path`/`static_serve` manual em `urls.py`. Cada template usa `{% load static %}` + `{% static 'css/tokens.css' %}` (nunca um caminho hardcoded tipo `assets/css/...`, que não existe mais). Essa escolha (Django servindo o próprio frontend) existe para evitar CORS/cookie cross-origin: autenticação é por **sessão/cookie do Django**, então frontend e API precisam estar na mesma origem.
Em produção, rodar `python manage.py collectstatic` (junta tudo em `STATIC_ROOT = BASE_DIR / "staticfiles"`) e servir esse diretório via whitenoise/nginx — `django.contrib.staticfiles` só serve automaticamente quando `DEBUG=True`. Uploads de usuário (ícones de `LinkFerramenta`) são um mecanismo separado: `MEDIA_URL`/`MEDIA_ROOT` em `settings.py`, servidos por `config/urls.py` via `static()` só quando `DEBUG=True` (em produção, servir `media/` também por whitenoise/nginx, igual ao `STATIC_ROOT`).
### Apps Django
Um único app, `portal_api/`:
| Arquivo | Conteúdo |
|---|---|
| `models.py` | `Usuario` (`AbstractUser` + `nome`, M2M `perfis`, M2M `departamentos` (pra `Departamento`, ver abaixo), campos cadastrais opcionais `codigo_folha`/`codigo_questor`/`codigo_tareffa`/`codigo_contabit`/`ramal` (`CharField`, `blank=True`) e `data_aniversario` (`DateField`, `null=True, blank=True`), `lideranca` (`BooleanField`, é gerente/coordenador) e M2M `liderados` (self-referential, `symmetrical=False`, `related_name="lideres"` — ver seção "Liderança" abaixo) — `email` já vem de `AbstractUser`, não precisou de campo novo; método `permissao_app(module_key, app_key)` — união genérica de um flag de `apps` entre os perfis vinculados), `Departamento` (só `nome`, `unique=True` — cadastro inline pela própria tela de Usuários, sem tela de administração dedicada como `PerfilAcesso`), `PerfilAcesso` (`permissoes` em `JSONField`, mesmo formato aninhado do frontend; mais o booleano dedicado `gerencia_permissoes`), `CompromissoAgenda`, `Favorito`, `WidgetUsuario`, `NotificacaoDispensada`, `LinkFerramenta` (`icone` é `ImageField`, requer Pillow), `LinkFerramentaFavorito` (favorito por usuário de um cartão de Links & Ferramentas — não confundir com `Favorito`), `AcessoGeralSecao`/`AcessoGeral` (cadastro de logins/acessos compartilhados da aplicação "Acessos Gerais", ver seção própria abaixo), `Ramal` (linha **avulsa** da tela de Ramais, sem `Usuario` por trás — colaboradores de verdade aparecem automaticamente na listagem, sem precisar de uma linha aqui; ver seção "Ramais" abaixo), `RamalAusencia` (período de ausência de um colaborador, com `esta_ativa()` calculando "ausente agora" em vez de armazenar), `TelefoneExterno` (subtela "Telefones Externos" de Ramais, sem `Usuario` por trás), `FuncaoTelefonia` (subtela "Funções de Telefonia" de Ramais, `Meta.ordering` por `comando` reproduz a ordem esperada sem campo de ordem manual), `ImportacaoPlanoSaude`/`ImportacaoPlanoSaudeLinha`/`ImportacaoPlanoSaudeAuditoria` (ferramenta "Importação de Plano de Saúde" em Utilitários, ver seção própria abaixo). |
| `catalogo.py` | Fonte única da verdade do catálogo de módulos/aplicações do menu (`MODULES`, `MODULE_APPS`) — exposto só leitura via `GET /api/catalogo/`. Ao adicionar uma seção/aplicação nova ao menu, editar **aqui**, não em `static/js/profiles.js` (que só cacheia o payload recebido). |
| `serializers.py` | `PerfilAcessoSerializer`, `DepartamentoSerializer`, `UsuarioResumoSerializer` (`id`/`nome`/`departamentos`, usado nos dois lados de `liderados` e por `/api/usuarios-resumo/`), `UsuarioSerializer` (escrita, aceita `senha`+`perfis`+`departamentos`+`liderados`)/`UsuarioListSerializer` (leitura, `perfis`/`departamentos`/`liderados` aninhados), `CompromissoAgendaSerializer` (`sou_dono`, `dono_nome`, `dono_username`), `FavoritoSerializer`, `WidgetUsuarioSerializer`, `NotificacaoDispensadaSerializer`, `LinkFerramentaSerializer`, `LinkFerramentaFavoritoSerializer`, `AcessoGeralSecaoSerializer`, `AcessoGeralSerializer`, `RamalSerializer` (só das linhas avulsas — ver seção "Ramais"), `RamalAusenciaSerializer`, `TelefoneExternoSerializer`, `FuncaoTelefoniaSerializer`, `ImportacaoPlanoSaudeCreateSerializer`/`ImportacaoPlanoSaudeListSerializer`/`ImportacaoPlanoSaudeDetailSerializer`/`ImportacaoPlanoSaudeLinhaSerializer`/`ImportacaoPlanoSaudeAuditoriaSerializer` (ver seção "Importação de Plano de Saúde"). |
| `permissions.py` | `PodeGerenciarPermissoes` — gate único de `gerencia_permissoes()` para as telas administrativas; `PermissaoApp(module_key, app_key)` — classe genérica reutilizável que checa `Usuario.permissao_app()`, instanciada por view (ex.: Links & Ferramentas e Ramais, ver seção própria abaixo). |
| `views.py` | `login_view`/`logout_view`/`csrf_view` (auth por sessão), `me_view` (usuário + `permissoes_efetivas` já unidas no servidor + `lideranca`/`liderados`), `trocar_senha_view`, `usuarios_resumo_view`, `meus_liderados_view` (ver seção "Liderança"), `departamentos_resumo_view` (ver "Ramais"), `catalogo_view`, e os `ModelViewSet` de perfis/departamentos/usuários/compromissos/favoritos/widgets/notificações dispensadas/links e ferramentas/favoritos de links e ferramentas/seções e linhas de Acessos Gerais/ramais/ausências de ramal/importações de plano de saúde e suas linhas. |
| `admin.py` | Django admin básico para todos os models (uso interno, não é a UI do portal). |
| `management/commands/seed_portal.py` | Recria os 8 perfis padrão + `gabriel`/`bruno` + as 13 linhas de `FuncaoTelefonia` + o seed de `CategoriaEvento`. |
| `management/commands/seed_indicador_desempenho.py` | Popula o primeiro histórico do Indicador de Desempenho (7 `IndicadorCriterio` + 5 `IndicadorPercentualTipo`, idempotente) com os valores da planilha antiga — ver seção "Indicador de Desempenho" abaixo. |
| `planos_saude/` | Pacote Python puro (sem ORM) com o pipeline de extração/casamento de "Importação de Plano de Saúde", portado de `projects/project/` — ver seção própria abaixo. |
| `custo_contratacao/` | Pacote Python puro (sem ORM) da ferramenta "Simulação de Custo de Contratação" (Geradoc) — `tabelas.py` (seed/default das faixas de INSS/IRRF, hoje editáveis via `ParametroFiscalCustoContratacao`), `calculo.py` (`ParametrosFiscais` dataclass + `calcula_custo_empregado`), `pdf.py` (`gera_pdf_simulacao`, via `reportlab`). Ver seção própria abaixo. |
| `indicadores/` | Pacote Python puro (sem ORM) da ferramenta "Indicador de Desempenho" (Geradoc) — `tipos.py` (deriva o tipo de colaborador por empresa via Tareffa), `leiaute.py` (leitura das planilhas Tareffa/Honorários via `openpyxl`), `pipeline.py` (orquestração, `processa_apuracao`), `entregas.py` (cálculo dos 3 critérios automáticos), `calculo.py` (composição dos percentuais Individual/Grupo/Departamento e valores em R$), `recibo.py` (PDF do recibo por colaborador, via `reportlab`). Ver seção própria abaixo. |
### API (sessão + CSRF, não token)
| Endpoint | Método | Uso |
|---|---|---|
| `/api/auth/csrf/` | GET | garante o cookie `csrftoken` |
| `/api/auth/login/` | POST | `{username, password}` → cria sessão |
| `/api/auth/logout/` | POST | encerra sessão |
| `/api/me/` | GET | usuário logado + `perfis` + `departamentos` (os próprios, pra alimentar o seletor de "Meu departamento" do Calendário Individual) + `gerencia_permissoes` + `permissoes_efetivas` (união já calculada no servidor) |
| `/api/me/senha/` | POST | `{senha_atual, nova_senha}` |
| `/api/me/liderados/` | PATCH | `{liderados: [id, ...]}` — só se `me.lideranca`; auto-gerenciamento de liderados (ver seção "Liderança") |
| `/api/catalogo/` | GET | módulos/aplicações/subgrupos do menu |
| `/api/feriados/?ano=AAAA` | GET | feriados nacionais + estaduais (PR) do ano pedido (default: ano atual), via lib `holidays` — ver "Feriados no Calendário Individual" abaixo |
| `/api/usuarios-resumo/` | GET | lista enxuta (`id`/`nome`) de usuários ativos — alimenta o seletor de liderados, sem exigir `gerencia_permissoes` (mesmo padrão de `/api/ramais/usuarios/`) |
| `/api/departamentos-resumo/` | GET | lista enxuta (`id`/`nome`) de departamentos — alimenta os botões de filtro do modal de consulta rápida de Ramais, exige só `ramais-visualizar` (não `gerencia_permissoes` como `/api/departamentos/`) |
| `/api/perfis/`, `/api/perfis/{codigo}/` | GET/POST/PUT/DELETE | CRUD de perfil — só quem tem `gerencia_permissoes` |
| `/api/departamentos/`, `/api/departamentos/{id}/` | GET/POST/PUT/DELETE | CRUD de departamento — só quem tem `gerencia_permissoes`; usado pela tela de Usuários pra listar o checklist e cadastrar um novo departamento inline (sem tela própria) |
| `/api/usuarios/`, `/api/usuarios/{id}/` | GET/POST/PATCH/DELETE | CRUD de conta — só quem tem `gerencia_permissoes`; `departamentos` é M2M igual `perfis` (lista de ids na escrita, objetos aninhados na leitura); `is_active` é gravável via PATCH (inativar/reativar, ver "Inativar usuário" abaixo) |
| `/api/compromissos/`, `/api/compromissos/{id}/` | GET/POST/PATCH/DELETE | GET já retorna só o que o usuário logado pode ver (próprios + `visibilidade="todos"` + `visibilidade="departamento"` com departamento em comum); campo `notificar_em` (calculado, ver "Calendário Individual e Widgets") indica quando o lembrete passa a valer; criar/editar com `visibilidade` em `departamento`/`todos` (inclusive todo `eh_evento=True`, que força `visibilidade="todos"`) exige `apps["calendario-individual-criar-evento"]` (ver "Eventos Corporativos" abaixo) |
| `/api/categorias-evento/`, `/api/categorias-evento/{id}/` | GET/POST/PATCH/DELETE | cadastro de categorias de evento (`nome`+`cor`) usado pelo Calendário Individual; GET livre a qualquer autenticado, escrita exige `apps["calendario-individual-criar-evento"]` — ver "Eventos Corporativos" abaixo |
| `/api/favoritos/`, `/api/favoritos/{app_id}/` | GET/POST/PATCH/DELETE | chave natural é `app_id`, não um id numérico; `ordem` é gravável via PATCH (drag-and-drop na grade de favoritos, ver "Favoritos" abaixo) |
| `/api/widgets/`, `/api/widgets/{tipo}/` | GET/POST/PATCH/DELETE | chave natural é `tipo`; `ordem` (reordenar por drag-and-drop) e `largura`/`altura` em px (redimensionamento) também são graváveis via PATCH — ver "Calendário Individual e Widgets" abaixo |
| `/api/notificacoes-dispensadas/`, `/api/notificacoes-dispensadas/{notif_id}/` | GET/POST/DELETE | chave natural é `notif_id` (ex.: `"tool-widgets"`, `"event-42"`); `notifications.js` usa GET pra filtrar o que já foi dispensado e POST a cada X/"Limpar tudo" |
| `/api/links-ferramentas/`, `/api/links-ferramentas/{id}/` | GET/POST/PATCH/DELETE | lista **compartilhada** (não por usuário); leitura exige `apps["links-ferramentas-visualizar"]` e escrita exige `apps["links-ferramentas-editar"]` em `permissoes["links-ferramentas"]` (`PermissaoApp`, gate por método em `get_permissions()` — ver "Modelo de permissões" abaixo); POST é `multipart/form-data` (aceita upload de `icone`); `ordem` sempre é atribuída pelo servidor na criação (ignora o que vier no payload), reordenar é PATCH trocando o `ordem` de dois itens |
| `/api/links-ferramentas-favoritos/`, `/api/links-ferramentas-favoritos/{link_id}/` | GET/POST/DELETE | favorito **por usuário** de um cartão (chave natural é `link_id`, o id do `LinkFerramenta` — mesmo padrão de `app_id`/`notif_id`); exige só `apps["links-ferramentas-visualizar"]` (favoritar não precisa de editar); só afeta a ordem de exibição em Links & Ferramentas e o widget "Links Favoritos", nunca o `ordem` compartilhado (ver seção "Links & Ferramentas" abaixo) |
| `/api/acessos-gerais-secoes/`, `/api/acessos-gerais-secoes/{id}/` | GET/POST/PATCH/DELETE | seções do cadastro "Acessos Gerais" (aplicação dentro da seção Links & Ferramentas); leitura exige `apps["acessos-gerais-visualizar"]`, escrita exige `apps["acessos-gerais-editar"]`; excluir uma seção também exclui (`CASCADE`) os acessos dela; GET só lista seções sem `perfis_restritos` ou com interseção com os perfis do usuário (ver "Acessos Gerais" abaixo) |
| `/api/acessos-gerais/`, `/api/acessos-gerais/{id}/` | GET/POST/PATCH/DELETE | linhas (acessos/logins) dentro de uma seção; mesma permissão de `acessos-gerais-secoes`; `ordem` é escopada por `secao` (servidor calcula `max(ordem)` só entre as linhas da mesma seção) — ver seção "Acessos Gerais" abaixo |
| `/api/ramais/` | GET | diretório **mesclado**: todo usuário ativo (linha montada do cadastro, sem precisar de nenhum registro extra) + linhas avulsas de `Ramal`; leitura exige `apps.visualizar` — ver seção "Ramais" abaixo |
| `/api/ramais/`, `/api/ramais/{id}/` | POST/PATCH/DELETE | CRUD só das linhas avulsas (`Ramal`, sem `Usuario` por trás); escrita exige `apps.editar` |
| `/api/ramais/usuarios/` | GET | lista enxuta (`id`/`nome`) de usuários ativos pra alimentar o `<select>` "Lista de Usuários" do modal de Criar Ausência — não é `/api/usuarios/` de propósito (ver seção "Ramais") |
| `/api/ramais/usuarios/{usuario_id}/` | PATCH | `{numero}` — grava direto em `Usuario.ramal`; é como a tela edita o ramal de um colaborador de verdade (exige `apps.editar`) |
| `/api/ramais-ausencias/`, `/api/ramais-ausencias/{id}/` | GET/POST/PATCH/DELETE | períodos de ausência; "ausente agora" nunca é lido daqui direto pelo frontend, vem calculado em `usuario_ausente`/`usuario_ausencia_ativa_id` na listagem de `/api/ramais/`; `PATCH` com `{"encerrada_manualmente": true}` encerra antes do previsto |
| `/api/telefones-externos/`, `/api/telefones-externos/{id}/` | GET/POST/PATCH/DELETE | subtela "Telefones Externos" de `ramais.html`; mesma permissão `PermissaoApp("ramais", ...)` do diretório de Ramais |
| `/api/funcoes-telefonia/`, `/api/funcoes-telefonia/{id}/` | GET/POST/PATCH/DELETE | subtela "Funções de Telefonia" de `ramais.html`; idem, mesma permissão de `ramais`; as 13 linhas padrão vêm de `seed_portal` |
| `/api/importacoes-plano-saude/`, `/api/importacoes-plano-saude/{id}/` | GET/POST | histórico + criação (ver seção "Importação de Plano de Saúde"); `PermissaoApp("utilitarios", "importacao-plano-saude")` (toggle único) pra todos os métodos; POST é `multipart/form-data` (planilha padrão + arquivo da operadora) e roda o pipeline de forma síncrona antes de responder |
| `/api/importacoes-plano-saude/operadoras/` | GET | `[{key, label}]` das operadoras registradas em `planos_saude.pipeline.OPERADORAS` — alimenta o `<select>` do formulário |
| `/api/importacoes-plano-saude/{id}/gerar/` | POST | monta o CSV (ou ZIP, se mais de um tipo de lançamento) a partir das linhas já revisadas/editadas e devolve como download binário; marca a importação como `concluida` |
| `/api/importacoes-plano-saude-linhas/{id}/` | GET/PATCH | edição de uma linha da revisão (todos os campos, não só valores); mesma permissão da importação, sem conceito de "dono" |
| `/api/regras-custeio-plano-saude/`, `/api/regras-custeio-plano-saude/{id}/` | GET/POST/PATCH/DELETE | banco de regras de custeio salvas (`nome`+`operadora`+`tipos_lancamento`+`custeio_por_tipo`+`observacoes`, ver "Regras de custeio salvas" abaixo) — mesma permissão de toggle único da ferramenta; lista compartilhada, sem "dono" |
| `/api/simulacao-custo-contratacao/gerar/` | POST | calcula (`portal_api.custo_contratacao.calculo.calcula_custo_empregado`) e devolve o PDF direto na resposta (`application/pdf`, sem persistir nada); `PermissaoApp`-like check manual via `permissao_app("geradoc", "simulacao-custo-contratacao")` — ver seção própria abaixo |
| `/api/parametros-fiscais-custo-contratacao/` | GET/PATCH | tabelas de INSS/IRRF + parâmetros da Lei 15.270/2025 usados pela simulação (`ParametroFiscalCustoContratacao`, singleton `pk=1`); mesma permissão da simulação, sem par visualizar/editar dedicado |
| `/api/indicadores-percentuais-tipo/` | GET/POST/DELETE | histórico de percentuais individual/grupo/departamento por tipo de colaborador (`IndicadorPercentualTipo`) — nunca editado in-place, só criado com `vigente_desde` novo; mesma permissão de toggle único `apps["indicador-desempenho"]` em `permissoes["geradoc"]` |
| `/api/indicadores-criterios/`, `/api/indicadores-criterios/{id}/` | GET/POST/PATCH/DELETE | CRUD do cadastro genérico de critérios (`IndicadorCriterio`) — nome/grupo/peso/período/papel/cálculo automático livres, editável pelo RH |
| `/api/indicadores-apuracoes/`, `/api/indicadores-apuracoes/{id}/` | GET/POST/DELETE | apuração mensal (`IndicadorApuracao`); POST é multipart (2 planilhas) e roda `indicadores.pipeline.processa_apuracao()` de forma síncrona dentro de um `transaction.atomic()`, persistindo colaboradores/empresas/respostas já calculados; DELETE também apaga os 2 arquivos de `MEDIA_ROOT` |
| `/api/indicadores-apuracoes/{id}/gerar/` | POST | gera um ZIP com um PDF de recibo por colaborador (`indicadores.recibo.gera_pdf_recibo`), a partir do que já está salvo (não reprocessa as planilhas); `colaborador_ids` opcional no corpo restringe a geração a só esses colaboradores (modal "Gerar Recibos" — um colaborador só, alguns específicos, por departamento ou todos); marca a apuração como `concluida` só quando a seleção cobre **todos** os colaboradores |
| `/api/indicadores-apuracoes/{id}/ajustar-grupo/`, `/recalcular-grupo/` | POST | ajusta (ou reverte) o `pct_grupo` de **todos** os colaboradores de um mesmo `gerente` na apuração de uma vez — "cada gerente representa um grupo" (ver seção própria abaixo) |
| `/api/indicadores-apuracoes/{id}/ajustar-departamento/`, `/recalcular-departamento/` | POST | idem, mas aplica a **todos** os colaboradores do `departamento` (id de um `IndicadorDepartamento`) informado no corpo (`{departamento, pct_departamento}`/`{departamento}`) — cada departamento tem sua própria meta de Departamento, ver "Departamento organizacional" abaixo |
| `/api/indicadores-departamentos/`, `/api/indicadores-departamentos/{id}/` | GET/POST/PATCH/DELETE | cadastro de departamentos (`IndicadorDepartamento`, nome/ativo) — mesma permissão de toggle único do Indicador de Desempenho, ver "Departamento organizacional" abaixo |
| `/api/indicadores-departamentos-gerentes/`, `/api/indicadores-departamentos-gerentes/{id}/` | GET/POST/PATCH/DELETE | relação gerente→departamento (`IndicadorDepartamentoGerente`, `nome_gerente` único) — mesma permissão, ver "Departamento organizacional" abaixo |
| `/api/indicadores-apuracoes/{id}/ajustar-honorario-empresa/` | POST | `{codigo_empresa, honorario}` — preenche (ou corrige) o honorário de uma empresa com `honorario_nao_encontrado=True` ou `honorario_ajustado_manualmente=True` de uma vez pra **todos** os colaboradores desta apuração que a têm (mesmo código), recalculando cada um (ver "Empresas sem Honorário"/"Empresas Ajustadas Manualmente" abaixo) |
| `/api/indicadores-apuracoes-colaboradores/{id}/` | GET/PATCH | ajuste manual do `pct_individual` de um colaborador (`pct_individual_ajustado_manualmente=True`); recalcula `valor_total` via `indicadores.calculo.recalcula_colaborador` |
| `/api/indicadores-apuracoes-colaboradores/{id}/recalcular/` | POST | reverte `pct_individual` pro modo automático (limpa o ajuste manual) e recalcula |
| `/api/indicadores-apuracoes-colaboradores/{id}/marcar-validado/` | POST | `{validado}` — checklist de revisão do RH, só grava o campo, sem recalcular nada (ver "Checklist de revisão do RH" abaixo) |
| `/api/indicadores-apuracoes-empresas/{id}/trocar-responsavel/` | POST | `{colaborador_id}` — reatribui essa linha (empresa+tipo) pra outro colaborador da mesma apuração, recalculando os dois (ver "Corrigir Responsável" abaixo) |
| `/api/indicadores-apuracoes-empresas/{id}/` | GET/PATCH | preenchimento manual do `honorario` de uma empresa com `honorario_nao_encontrado=True` (código não casou com a planilha de Honorários Por Cliente); zera essa flag e recalcula o colaborador |
| `/api/indicadores-apuracoes-respostas/{id}/` | GET/PATCH | edição de uma resposta de critério (SIM/NÃO/NÃO FAZ/NÃO SE APLICA) já existente; recalcula o colaborador |
| `/api/indicadores-apuracoes-respostas/aplicar-em-lote/` | POST | `{resposta_ids, valor}` — aplica o mesmo valor a várias respostas de uma vez (seleção múltipla da tela de revisão), recalculando todos os colaboradores afetados |
### Frontend consumindo a API
`static/js/api.js` é a base de tudo: `pidApiRequest(path, options)` faz `fetch` com `credentials:"include"`, injeta `X-CSRFToken` (lendo o cookie `csrftoken`, buscando-o via `/api/auth/csrf/` primeiro se ainda não existir) em métodos não seguros, e redireciona pra `index.html` em 401 por padrão (`redirectOn401: false` para os poucos casos onde 401 é esperado, como o próprio login).
`access.js` expõe `pidGetMe()` — chamada única e **cacheada por página** (`pidMePromise`) para `GET /api/me/`. Cada arquivo controlador (`account.js`, `favorites.js`, `widgets.js`, `profiles.js`, `users-admin.js`, `calendar-individual.js`, `links-ferramentas.js`, `acessos-gerais.js`, `ramais-lookup.js`) chama `pidGetMe()` no início do seu próprio `DOMContentLoaded`, mas como todos rodam antes do primeiro `await` resolver, a promise cacheada garante **uma única requisição de rede** por carregamento de página, não uma por arquivo.
`pidApiRequest` (em `api.js`) detecta `body instanceof FormData` e, nesse caso, **não** faz `JSON.stringify` nem define `Content-Type` manualmente — deixa o browser montar o `multipart/form-data` com o boundary certo. Usado pelo upload de `icone` em Links & Ferramentas e pelos dois arquivos anexados em "Nova Importação" de Plano de Saúde; todo o resto da API é JSON puro. A única resposta binária da API (`/importacoes-plano-saude/{id}/gerar/`, que devolve CSV/ZIP) não passa por `pidApiRequest` — usa um `fetch` manual dedicado (ver seção "Importação de Plano de Saúde").
`pidApplyAccessVisibility` não recalcula mais união de permissões no cliente — usa `me.permissoes_efetivas`, já unida no backend (`permissoes_efetivas()` em `views.py`).
## Páginas
| Página | Papel |
|---|---|
| `index.html` | Login. POST `/api/auth/login/`. |
| `portal.html` | Shell principal: busca de aplicações, grade de favoritos, seção de Widgets. |
| `calendario-individual.html` | Agenda pessoal: grade mensal + modal de criar/editar compromisso. |
| `perfis-acesso.html` | CRUD de perfis de acesso (lista + edição com abas Permissões/Usuários do Escritório). |
| `usuarios.html` | CRUD de contas de usuário (lista + edição com checklist de perfis). |
| `links-ferramentas.html` | Grade de cartões de atalho para ferramentas externas; reordenar/incluir/remover só com `apps["links-ferramentas-editar"]` (ver seção própria abaixo). |
| `acessos-gerais.html` | Cadastro de acessos/logins compartilhados organizados em seções e linhas, com popup de detalhes; criar/editar/excluir seções e linhas só com `apps["acessos-gerais-editar"]` (ver seção "Acessos Gerais" abaixo). |
| `ramais.html` | Diretório de ramais internos, filtros por nome/departamento; adicionar/editar ramal, criar ausência e excluir só com `apps.editar` em `ramais` (ver seção "Ramais" abaixo). |
| `importacao-plano-saude.html` | Ferramenta de Utilitários: histórico + nova importação (upload) + revisão/geração do arquivo de lançamento de plano de saúde (ver seção "Importação de Plano de Saúde" abaixo). |
| `custo-contratacao.html` | Ferramenta de Geradoc: formulário de simulação de custo de contratação (Empregado CLT) + painel colapsável de parâmetros fiscais, gera um PDF (ver seção "Simulação de Custo de Contratação" abaixo). |
| `indicador-desempenho.html` | Ferramenta de Geradoc: histórico de apurações + nova apuração (upload das 2 planilhas) + cadastro de critérios/percentuais + revisão/geração dos recibos em PDF do Indicador de Desempenho do Fiscontábil (ver seção própria abaixo). |
O item "Calendário De Paula" no menu **não é uma página local** — é um `<a href="#" id="calendario-depaula-btn">` (continua favoritável, já que ainda é um `<a class="nav-item">` — ver "Favoritos" abaixo) cujo clique é interceptado em `sidebar.js` (`PID_CALENDARIO_DEPAULA_URL`) pra abrir `https://depaula-tvcorporativa.lovable.app/calendario` num modal com `<iframe>` (`#calendario-depaula-modal`, presente em todo shell) em vez de navegar — mesmo padrão do modal "Novo Chamado" de Ramais (`.ram-chamado-*` em `ramais.css`/`ramais.js`), só que genérico o bastante (`.iframe-modal-*` em `components.css`) pra existir em todo shell, não só em `ramais.html`. Funciona porque esse host (mesmo domínio do "Novo Chamado") não bloqueia ser embutido via `X-Frame-Options`/CSP, ao contrário do Asana (ver "Solicitações" abaixo) — só foi possível confirmar isso testando de fato, não é garantia geral por domínio. Não recriar um `calendario.html` interno sem confirmar com o usuário; o antigo foi removido de propósito.
## Ordem de `<script>` e por que ela não quebra nada
Todas as páginas-shell (todas exceto `index.html`) carregam o mesmo prefixo de scripts, na mesma ordem: `api.js → profiles.js → auth.js → access.js → account.js → favorites.js → events.js → ...`, seguido de scripts específicos da página. Nenhum script usa `defer` exceto `theme.js` (que fica no `<head>`).
Isso importa porque, por exemplo, `access.js` chama `pidRequireAuth()` de `auth.js`, que só aparece **antes** dele na tag `<script>` — mas mesmo quando a ordem fosse invertida funcionaria, porque toda chamada cross-arquivo acontece dentro de um callback de `document.addEventListener("DOMContentLoaded", ...)`, nunca no nível superior do script. Como todo `<script>` sem `defer` executa (e portanto declara suas funções) antes do evento `DOMContentLoaded` disparar, a ordem relativa entre arquivos não importa — só importa que todos estejam presentes na página antes desse evento. Ao adicionar um novo arquivo JS compartilhado, não é preciso se preocupar em "colocá-lo antes de quem o usa", desde que toda chamada fique dentro de um handler de `DOMContentLoaded` (ou de uma função só invocada por um).
Padrão de guarda por página: `profiles.js`, `users-admin.js` e `widgets.js` verificam a existência do elemento raiz da própria tela (`#pa-list-view`, `#ua-list-view`, `#widgets-grid`) e retornam cedo se não estiverem na página certa — por isso são incluídos em todo shell mesmo quando só uma página usa a parte de "controlador" (`profiles.js` também expõe funções de dados — `pidFetchPerfis`, `pidFetchUsuarios`, `pidFetchCatalogo` — reaproveitadas por `users-admin.js`).
## Armazenamento
| Onde | O quê |
|---|---|
| `localStorage` (`pid_theme`, `pid_color_theme`) | Só preferência de tema — ver `theme.js`. |
| Postgres, via API | Tudo o mais: sessão (cookie do Django), usuários, perfis de acesso, favoritos, widgets, compromissos do Calendário Individual, notificações dispensadas. |
`notifications.js` usa uma lista mockada em memória (`PID_NEW_TOOLS_NOTIFICATIONS`) para os anúncios de "nova ferramenta" — os itens de compromisso vêm de `/api/compromissos/` de verdade. O conteúdo das notificações continua mockado/derivado a cada carregamento, mas **quais delas o usuário já dispensou** (X individual ou "Limpar tudo") persiste por usuário via `NotificacaoDispensada`/`/api/notificacoes-dispensadas/` — por isso um item dispensado não reaparece depois de um reload.
**Histórico de notificações** (botão "Histórico" ao lado de "Limpar tudo", em `#notif-history-modal` — presente nos 7 shells que têm o sino, tudo exceto `index.html`): não é um model novo, é uma segunda leitura da mesma tabela `NotificacaoDispensada` — o sino ativo mostra `!dismissedIds.includes(id)`, o histórico mostra o inverso (`dismissedIds.includes(id)`). A diferença entre os dois pools de candidatos usados (`notifications.js`) é proposital: o sino usa `pidEventosElegiveisAgora()` (só eventos com `data >= hoje` e `notificar_em` já atingido, capado em 5 pra não lotar o dropdown), enquanto o histórico usa `allEventNotifications` (todos os compromissos que o usuário pode ver, sem nenhuma das duas restrições) — um item dispensado pode não estar mais no recorte "elegível agora" (compromisso já passou, ou o lembrete não bateu ainda depois de uma edição), mas ainda precisa aparecer no histórico. Cada item do histórico tem um botão "Restaurar" (`DELETE /api/notificacoes-dispensadas/{notif_id}/`, já existia como endpoint, só não tinha consumidor no frontend) que remove o registro de dispensa; a notificação só volta a aparecer no sino de fato se ainda estiver no pool "elegível agora" (ex.: restaurar uma notificação de ferramenta sempre reaparece no sino, já que esse pool é estático; restaurar um compromisso muito antigo não reaparece, porque ele não está mais entre os 5 mais próximos elegíveis — o histórico continua mostrando, já que sua lista não tem esse recorte).
## Modelo de permissões (Perfis de Acesso)
O catálogo de módulos/aplicações do menu vive só no backend agora (`portal_api/catalogo.py`) e é buscado uma vez por `profiles.js` via `GET /api/catalogo/` — **não editar mais um `PID_MODULES`/`PID_MODULE_APPS` hardcoded no frontend**; a edição correta é em `catalogo.py`. 11 das 14 seções do menu têm sub-aplicações configuráveis individualmente (`portais`, `geradoc`, `relatorios`, `relatorios-gerenciais`, `utilitarios`, `integracoes`, `auditorias`, `solicitacoes`, `links-ferramentas`, `ramais`, `calendario-individual`); as outras 3 (`principal`, `calendario`, `administracao`) só têm um toggle de módulo, sem filhos. Em `auditorias`, cada entrada pode ser um subgrupo com `tools` aninhadas (ex.: "Consultoria Tributária" → "Controle Simples Nacional") — categorias reais que agrupam ferramentas reais. Em `ramais` e em `links-ferramentas`, o mesmo formato de subgrupo é reaproveitado por outro motivo: cada subgrupo ali **é** uma subtela/aplicação real da seção (ex.: "Ramais"/"Telefones Externos" dentro de `ramais`; "Links & Ferramentas"/"Acessos Gerais" dentro de `links-ferramentas`), e as `tools` dentro de cada subgrupo não são aplicações de verdade — são os dois níveis de acesso (visualizar/editar) daquela subtela (ver "Padrão visualizar/editar" abaixo). Em `calendario-individual`, o único subgrupo (`calendario-individual-eventos`) tem uma **única** `tool` (`calendario-individual-criar-evento`) em vez de um par visualizar/editar — a visualização do módulo em si já é liberada a todo perfil (está em `BASE_KEYS`), só a criação/gestão de eventos corporativos e categorias é restrita (ver "Eventos Corporativos" abaixo). Em `geradoc`, `simulacao-custo-contratacao` e `indicador-desempenho` são dois apps flat (sem subgrupo), cada um com permissão de **toggle único** — mesmo espírito de `importacao-plano-saude` em Utilitários (quem tem acesso faz o fluxo inteiro, sem par visualizar/editar).
Formato de perfil no banco (`PerfilAcesso.permissoes`, `JSONField`):
```json
{
"<moduleKey>": { "enabled": true, "apps": { "<appKey>": true } }
}
```
Um usuário pode estar vinculado a **mais de um perfil** (M2M `Usuario.perfis`). A união de permissões (`.some(...)`/`any(...)` sobre todos os perfis vinculados) agora é calculada **no servidor**, em `permissoes_efetivas()` (`portal_api/views.py`) — o frontend só consome o resultado já pronto via `me.permissoes_efetivas`. As duas exceções ao padrão "checar `permissoes_efetivas[chave].enabled`":
- `data-section="perfis-acesso"` e `data-section="usuarios"` (dentro de Administração) são gateados por `gerencia_permissoes`, não por `permissoes_efetivas.administracao.enabled`.
- O selo "Restrito" ao lado de Relatórios Gerenciais (`[data-restricted-badge]`) é mostrado se algum perfil vinculado tiver `nome === "Diretoria"` — um match de nome fixo, não uma flag de permissão.
### Padrão visualizar/editar (Links & Ferramentas, Acessos Gerais, Ramais e futuros módulos parecidos)
Alguns módulos não são só "lista de aplicações que aparecem ou não no menu" — têm uma ou mais telas próprias com conteúdo administrável (adicionar/remover/reordenar), que pedem dois **níveis** de acesso, não um: **visualizar** (ver a tela) e **editar** (mudar o conteúdo dela). Em vez de criar um `BooleanField` dedicado por módulo (o que foi tentado numa rodada e revertido — não escala pra "várias aplicações com a mesma funcionalidade"), o padrão adotado é modelar cada aplicação como um **subgrupo** com dois `tools` (visualizar/editar) dentro do módulo em `catalogo.MODULE_APPS` — mesmo formato de subgrupo já usado em Auditorias/Ramais:
```python
"links-ferramentas": [
{
"key": "links-ferramentas-cartoes",
"label": "Links & Ferramentas",
"tools": [
{"key": "links-ferramentas-visualizar", "label": "Visualizar"},
{"key": "links-ferramentas-editar", "label": "Editar (reordenar, incluir e remover cartões)"},
],
},
{
"key": "acessos-gerais",
"label": "Acessos Gerais",
"tools": [
{"key": "acessos-gerais-visualizar", "label": "Visualizar"},
{"key": "acessos-gerais-editar", "label": "Editar (criar/editar/excluir seções e acessos)"},
],
},
],
```
`links-ferramentas` nasceu com só um par `visualizar`/`editar` flat (sem subgrupo, já que só existia uma aplicação na seção); virou dois subgrupos quando "Acessos Gerais" foi adicionado como uma segunda aplicação dentro da mesma seção — a mesma evolução que `ramais` já tinha passado antes (ver "Navegação por abas em `ramais.html`" abaixo). Cada chave de `tool` é prefixada com o nome da aplicação (`links-ferramentas-visualizar`, não só `visualizar`) porque `permissoes[module_key]["apps"]` é um dict **achatado** — todas as `tools` de todos os subgrupos do módulo compartilham o mesmo namespace, então chaves genéricas colidiriam entre as duas aplicações.
Isso reaproveita 100% a árvore de permissões que já existe (`renderTree()`/`renderEntry()`/`renderLeaf()` em `profiles.js`, sem nenhum código de UI novo) — na tela de edição de perfil, "Links & Ferramentas" aparece expansível com "Links & Ferramentas" e "Acessos Gerais" como subgrupos, cada um expansível de novo em "Visualizar"/"Editar", do mesmo jeito que "Auditorias" mostra "Consultoria Tributária" → "Controle Simples Nacional". No backend, a checagem usa `Usuario.permissao_app(module_key, app_key)` (união entre os perfis vinculados, mesma lógica de `permissoes_efetivas()`) e a classe genérica `PermissaoApp(module_key, app_key)` em `permissions.py`, instanciada por view — nenhuma subclasse nova é necessária pra outro módulo/aplicação adotar o mesmo padrão, só instanciar com outra `app_key`.
**Cuidado com `seed_portal.py`**: o módulo continua tendo seu próprio `enabled` (visibilidade no menu) e, se estiver em `BASE_KEYS`/`SECTORAL_KEYS` etc., `catalogo.permissions_from_keys()` habilita **todos** os apps de um módulo enabled de uma vez — incluindo todo `*-editar`. Por isso `seed_portal.py` força `permissoes["links-ferramentas"]["apps"]["links-ferramentas-editar"] = False`, `permissoes["links-ferramentas"]["apps"]["acessos-gerais-editar"] = False` e `permissoes["ramais"]["apps"]["ramais-editar"] = False` (+ as outras duas subtelas administráveis de Ramais) explicitamente pra todo perfil que não seja "Integração e Inovação" (código 8, `chaves=None` → todos os apps `True` de propósito), depois de gerar o dict — sem esse override, qualquer perfil com o módulo habilitado nasceria com poder de editar tudo. Ao adicionar uma aplicação nova nesse padrão (dentro de um módulo existente ou não), replicar esse mesmo cuidado no seed.
### Popup "Nova Aplicação" (gerenciar acesso por aplicação, entre perfis)
Botão `#pa-app-search-btn` ao lado de "Novo Perfil" (`perfis-acesso.html`) abre `#pa-app-search-modal` — o caminho inverso da árvore de permissões: em vez de abrir um perfil e marcar módulo por módulo, o usuário busca uma aplicação/ferramenta pelo nome e vê/gerencia **todos os perfis** que têm acesso a ela numa tabela só.
- **Fonte dos dados — 100% reaproveitado, sem endpoint novo**: `pidFlattenAplicacoes()` (`profiles.js`) achata `PID_MODULES` × `PID_MODULE_APPS` (já carregados de `GET /api/catalogo/` no load da página) numa lista plana de "aplicações" — uma por entrada de `MODULE_APPS`, seja ela um app simples ou um subgrupo com `tools` (mesma unidade usada em `renderEntry()` da árvore). A busca (`renderAppSearchResults()`) casa o termo contra o label da aplicação, o label do módulo **e** o label de cada `tool` aninhada — esse último é o que permite achar, por exemplo, "Controle Simples Nacional" (o `tool` real dentro do subgrupo "Consultoria Tributária" de Auditorias) mesmo a unidade selecionável sendo o subgrupo inteiro.
- **Painel de gerenciamento** (`renderAppManageTable()`): ao clicar num resultado, mostra uma tabela com uma linha por perfil (`profiles`, o mesmo array já carregado pela tela) e uma coluna de checkbox por `tool` — para app simples sem subgrupo, uma coluna única "Acesso". O cabeçalho de cada coluna usa `tool.label.split(" (")[0]` (corta o parêntese explicativo tipo "Editar (reordenar, incluir e remover cartões)" → "Editar"), sem precisar de um label curto dedicado no catálogo.
- **Salva na hora, por checkbox** (decisão explícita do usuário — sem botão "Salvar" no popup): cada `change` dispara `PATCH /api/perfis/{codigo}/` só com `{permissoes: perfil.permissions}` (`pidUpdatePerfilPermissoes`, PATCH parcial — o `ModelViewSet` já aceita, `PerfilAcessoSerializer` não exige os outros campos fora de `partial_update`). Erro de rede reverte o checkbox e o estado em memória, com um `alert()` simples (mesmo padrão de outros toggles imediatos do app, ex. inativar usuário).
- **Conceder acesso habilita o módulo automaticamente** (decisão explícita do usuário): se o checkbox marcado pertence a um módulo com `enabled=false` naquele perfil, o toggle também vira `perm.enabled = true` no mesmo PATCH — sem isso, o perfil ganharia a chave em `apps` mas o item continuaria escondido no menu (`access.js` esconde o `nav-group`/`nav-subitem` inteiro por `enabled`, não só por app). **Revogar não desabilita o módulo de volta** (outras aplicações dele podem seguir em uso por aquele perfil).
- Perfis inativos (`ativo=False`) aparecem na tabela com o selo `.status-pill--inativo` (mesmo componente da coluna "Status" de `usuarios.html`), sem serem excluídos da lista — nada nesse popup impede gerenciar o acesso deles.
## Inativar/reativar usuário (usuarios.html)
Usa o campo `is_active` que já vem de `AbstractUser` — não foi criado nenhum campo/migração novo, só exposto em `UsuarioSerializer`/`UsuarioListSerializer` e ligado na UI. `is_active=False` já é suficiente pro Django bloquear o acesso sozinho, sem nenhum código extra de autenticação:
- **Login novo**: `authenticate()` (usado em `login_view`) roda via `django.contrib.auth.backends.ModelBackend`, que internamente chama `user_can_authenticate()` e recusa (`None`) qualquer usuário com `is_active=False`, mesmo com a senha certa. Como isso faz `authenticate()` retornar `None` tanto pra senha errada quanto pra usuário inativo, `login_view` faz uma checagem manual **só no caminho de falha** (`Usuario.objects.filter(username=username, is_active=False).first()` + `check_password()`) pra devolver uma mensagem diferente ("Este usuário está inativo...", 403) só quando a senha bate mas a conta está inativa — sem essa checagem extra, qualquer tentativa com credenciais erradas ou inexistentes continua caindo no genérico "Login ou senha inválidos." (401), pra não revelar se um username existe.
- **Sessão já aberta**: também não precisa de nenhum middleware/permissão customizado — `ModelBackend.get_user(user_id)` (chamado pelo Django a cada request pra popular `request.user` a partir da sessão) também recusa usuários inativos, então na próxima requisição depois de desativado o usuário vira `AnonymousUser` automaticamente e `IsAuthenticated`/`PodeGerenciarPermissoes` já barram sozinhos. Ou seja: desativar alguém já derruba o acesso na mesma hora, não só impede o próximo login.
Na UI (`users-admin.js`/`usuarios.html`): coluna "Status" na lista (`.status-pill`/`.status-pill--ativo`/`.status-pill--inativo`, mesmo componente que já existia pro `PerfilAcesso.ativo`) e um botão de alternar (ícone de "power") na linha, ao lado de editar/excluir — `PATCH /api/usuarios/{id}/` com `{is_active: !atual}`, com confirmação via `window.confirm`. O checkbox "Usuário ativo" no formulário de edição faz a mesma coisa (útil quando já se está editando outros campos). Os dois lugares bloqueiam **auto-desativação** (mesmo padrão de guarda já usado pra "não pode excluir a si mesmo": checagem só no frontend, `id === me.id`) — no formulário isso aparece como o checkbox desabilitado (`disabled`) quando `account.id === me.id`, em vez de um alerta.
## Liderança (gerente/coordenador) e o modal "Gerenciar Usuário"
`Usuario.lideranca` (booleano) marca um usuário como gerente/coordenador de outros; `Usuario.liderados` é um M2M **auto-referenciado** (`"self"`, `symmetrical=False`, `related_name="lideres"`) — ou seja, "A lidera B" não implica "B lidera A". Exemplo: marcar `lideranca=True` em "debora" e incluir "gabriel" em `liderados` representa "debora é gerente de gabriel".
Dois lugares gravam essa mesma relação:
- **Tela de Usuários** (`usuarios.html`/`users-admin.js`, só quem tem `gerencia_permissoes`): seção "Liderança" no formulário de edição — checkbox "É gerente ou coordenador de outros usuários" (`#ua-lideranca`) libera (`hidden`) uma `.checklist-box` (`#ua-liderados-checklist`) com todos os outros usuários cadastrados (a própria conta sendo editada é excluída da lista — mesmo padrão de guarda "frontend-only" já usado pra "não pode excluir a si mesmo"/"não pode se auto-desativar", não há checagem equivalente no backend). Salvar envia `lideranca`+`liderados` (array de ids) no mesmo payload de `PATCH`/`POST /api/usuarios/`.
- **Modal "Gerenciar Usuário"** (`account.js`, disponível em todo shell via o item "Gerenciar Usuário" no dropdown da conta — substituiu o antigo botão direto "Alterar senha"): abre `#manage-account-modal`, que sempre tem um botão "Alterar senha" (que fecha esse modal e abre o `#password-modal` já existente, mesmo fluxo de antes) e, só se `me.lideranca` for `true`, uma segunda seção com a mesma `.checklist-box` de liderados — permitindo que o próprio gerente/coordenador se autogerencie sem precisar de acesso à tela administrativa de Usuários. Essa lista vem de `GET /api/usuarios-resumo/` (não de `/api/usuarios/`, que exige `gerencia_permissoes`) e salvar dispara `PATCH /api/me/liderados/`, que grava na mesma `Usuario.liderados` — `meus_liderados_view` recusa (403) se `request.user.lideranca` for `False`, já que só faz sentido pra quem tem o checkbox marcado.
**Busca por nome/departamento e layout em duas linhas**: `UsuarioResumoSerializer` (usado por `/api/usuarios-resumo/` e por `liderados` aninhado em `UsuarioListSerializer`/`/api/me/`) expõe também `departamentos` (nested `DepartamentoSerializer`), não só `id`/`nome`. Os dois pontos que renderizam o checklist de liderados (`users-admin.js`/`account.js`) usam isso pra: (a) cada item (`.checklist-item`) mostrar o nome e, numa segunda linha abaixo (`.checklist-item__info` empilha os dois em coluna), os departamentos do candidato unidos por vírgula (`—` se nenhum) — layout em duas linhas com quebra normal (não uma só linha com `text-overflow: ellipsis`) porque truncar cortava departamentos no meio quando o usuário tinha mais de um vinculado; (b) um campo de busca (`.checklist-search`, `#ua-liderados-search`/`#manage-account-liderados-search`) que filtra a lista pelo nome do usuário **ou** pelo texto dos departamentos (`String.includes`, case-insensitive) — qualquer um dos dois casa. A seleção de checkboxes é mantida em memória num `Set` (`lideradosSelecionados`, um por tela) em vez de lida direto do DOM, porque filtrar re-renderiza `innerHTML` e apagaria o estado de quem estivesse marcado mas momentaneamente fora do filtro; um listener de `change` delegado no container (`.checklist-box`) atualiza esse `Set` a cada clique, e o array final enviado à API vem de `Array.from(set)`, não de uma querystring nos checkboxes visíveis.
**"Marcar todos os resultados da busca"** (`.checklist-select-all`, `#ua-liderados-select-all`/`#manage-account-liderados-select-all`): opera só sobre o subconjunto **filtrado** pela busca no momento (não sobre todos os candidatos) — marcar adiciona o id de cada usuário filtrado ao `Set`, desmarcar remove; a cada re-render, o próprio estado desse checkbox é recalculado a partir do filtro atual (`checked` se todos os filtrados estão no `Set`, `indeterminate` se só parte, `disabled` se a busca não retornou ninguém), então ele reflete o resultado visível, não um total geral fixo.
`.checklist-box`/`.checklist-item` (+ `.checklist-item__nome`/`.checklist-item__departamento`/`.checklist-empty`/`.checklist-search`, `components.css`) é o componente genérico de "lista com checkbox, coluna secundária e busca" reaproveitado pelos três checklists de `usuarios.html` (Perfis de Acesso, Departamento, Liderados — os dois primeiros sem coluna/busca, só o layout base) **e** pelo checklist de liderados do modal "Gerenciar Usuário" — por isso mora em `components.css` (carregado em todo shell), não em `perfis-acesso.css` (só carregado em `usuarios.html`/`perfis-acesso.html`/`ramais.html`), onde vivia antes de existir um segundo consumidor fora dessas três páginas.
## Favoritos: como o ID de uma aplicação é derivado
`favorites.js` não depende de nenhum atributo `data-*` dedicado para identificar "o que é favoritável" — ele varre `.sidebar a.nav-item, .sidebar a.nav-subitem` e deriva um ID estável a partir da própria estrutura/texto do menu (`pidCollectFavoritableApps`), igual a antes da migração. Esse ID é o que vira `app_id` em `POST /api/favoritos/` e na URL de `DELETE /api/favoritos/{app_id}/`:
- Se o `<li>` do link já tem `data-section`, o ID é esse valor (ex.: `"ramais"`).
- Caso contrário (é um sub-item dentro de um `nav-group`), o ID é `"<data-section do grupo pai>__<slug do texto do link>"` (ex.: `"portais__portal-do-cliente"`).
O slug (`pidSlug`) normaliza acentos (NFD) e troca sequências de caracteres não `[a-z0-9]` por `-`. Se o texto de um label mudar, o `app_id` derivado muda junto (favoritos existentes referenciando o ID antigo deixam de casar).
**Reordenar os cards favoritos**: `Favorito.ordem` (`PositiveIntegerField`, `Meta.ordering = ["ordem", "id"]`) — mesmo padrão de `LinkFerramenta`/`WidgetUsuario`: `FavoritoViewSet.perform_create` atribui `ordem = max(ordem atual do usuário) + 1`, e reordenar é drag-and-drop nativo em `#app-card-grid` (`favorites.js`, `dragstart`/`dragover`/`drop`, `PATCH /api/favoritos/{app_id}/` só nos itens cujo `ordem` mudou) — mesma mecânica dos outros dois. `.app-card` inteiro é `draggable="true"` (não precisa de um handle separado como os widgets, já que não tem `resize` pra conflitar); o botão de remover (`.app-card__remove`) é `draggable="false"` pra não interferir.
## Calendário Individual e Widgets
Compromissos (`CompromissoAgenda`) têm um dono (`dono`, FK) e um campo `visibilidade` (`"somente_eu"`/`"departamento"`/`"todos"`, substituiu a antiga flag booleana `compartilhado_com_perfil` — perfil de acesso deixou de ser o critério de compartilhamento). `GET /api/compromissos/` (`CompromissoAgendaViewSet.get_queryset`) já retorna: (a) sempre os próprios compromissos do usuário; (b) todo compromisso com `visibilidade="todos"`, pra qualquer usuário do portal, sem checar perfil/departamento; (c) compromissos com `visibilidade="departamento"` só se `departamento_compartilhado` (FK, `on_delete=SET_NULL`) for um dos departamentos do usuário logado — a lógica de "visível para quem" mora só no backend. O campo `sou_dono` (calculado no serializer) substitui o antigo `ownerLogin === login` do cliente; só o dono edita/exclui (`CompromissoAgendaViewSet.get_object` levanta `PermissionDenied` se não for o dono tentando escrever).
Ao escolher `visibilidade="departamento"` no modal (`calendario-individual.html`/`calendar-individual.js`), um segundo campo aparece (`#ic-event-department-field`) pra escolher **qual** dos próprios departamentos do dono recebe o compartilhamento — decisão explícita do usuário, já que `Usuario.departamentos` é M2M (pode ter mais de um) e "meu departamento" sozinho seria ambíguo nesse caso. As opções desse `<select>` vêm de `me.departamentos` (adicionado a `/api/me/` só pra isso — antes esse endpoint não expunha os próprios departamentos do usuário logado, só o de outros via `UsuarioResumoSerializer`). `CompromissoAgendaSerializer.validate()` exige `departamento_compartilhado` quando `visibilidade="departamento"` e recusa qualquer departamento que não esteja entre os do próprio dono (`request.user.departamentos`) — mesmo que o cliente tente forçar um id de departamento alheio no payload; para as outras duas visibilidades, `departamento_compartilhado` é sempre zerado no servidor, ignorando o que vier no payload.
**Filtro por categoria e cores no calendário** (`.calendar-filters`/`.filter-chip` em `calendario.css` — já existiam no CSS sem nenhum consumidor antes desta funcionalidade): dentro de `.calendar-header`, ao lado do título do mês e do botão "Novo Compromisso" (mesma linha, não numa faixa própria abaixo — `flex-wrap: wrap` no header cobre o caso de não caber tudo numa linha só), uma barra de chips clicáveis (multi-seleção, sem exclusividade) filtra o que aparece no calendário por `pidEventoCategoria(ev)` (`calendar-individual.js`), que não é exatamente `ev.visibilidade` — um compromisso `"somente_eu"` que não é meu (`!ev.sou_dono`) só pode ter chegado pela regra de liderança abaixo, então vira a categoria `"equipe"`, distinta de `"somente_eu"` (meus próprios); e todo `ev.eh_evento` vira a categoria `"evento"` **antes** de qualquer outra checagem (ver "Eventos Corporativos" abaixo), mesmo já sendo sempre `visibilidade="todos"`. As 5 categorias (`somente_eu`/`departamento`/`todos`/`equipe`/`evento`) têm cor fixa própria (`.calendar-event--*` em `calendario.css`) e o chip ativo de cada uma usa a mesma cor — o próprio filtro funciona como legenda. `"somente_eu"` é a exceção: usa `--accent` (o tema de cor que o usuário escolheu, não uma cor fixa); as outras quatro usam tokens fixos novos (`--gold`, reaproveitado do antigo "compartilhado"; `--teal` e `--slate`, adicionados só pra isso em `tokens.css`; `--coral`, adicionado depois só pra `"evento"` — todos com variante mais escura no tema claro pro contraste do texto escuro fixo `#1a1721`) — escolhidos deliberadamente fora das 5 cores de tema selecionáveis (roxo/azul/verde/âmbar/rosa) pra nunca coincidir visualmente com o que `--accent` pode assumir. O chip "Minha equipe" (`#ic-filter-equipe`) só aparece (`hidden`) se `me.lideranca`; o chip "Eventos" (`data-filter="evento"`) é sempre visível, já que qualquer perfil pode ver eventos corporativos (só criar um é restrito). Por padrão todos os chips visíveis nascem `is-active` (mostra tudo que o usuário pode ver). Clique simples troca a seleção pra **só** aquele filtro (`activeFilters.clear()` + adiciona só o clicado), exceto se esse filtro já for o único ativo — nesse caso (`activeFilters.size === 1 && activeFilters.has(filtro)`) o clique volta pra visualização padrão (`selecionarTodosOsFiltros()`, todos os chips visíveis ativos), pra sempre existir um caminho de volta ao estado "ver tudo" sem precisar de Shift. `Shift`+clique acrescenta/remove esse filtro dos já selecionados (`event.shiftKey`, mesmo padrão de seleção de arquivos do SO) — é assim que dá pra combinar mais de uma categoria ao mesmo tempo.
**Eventos Corporativos** (`CategoriaEvento`, `CompromissoAgenda.eh_evento`/`categoria`/`local`/`modalidade`/`descricao`): compromissos com `visibilidade` em `departamento`/`todos` deixaram de ser livres pra qualquer usuário — criar ou editar um compromisso nesses dois níveis (o que inclui automaticamente todo `eh_evento=True`, já que a validação força `visibilidade="todos"` antes de checar permissão) agora exige `apps["calendario-individual-criar-evento"]` em `permissoes["calendario-individual"]` (`CompromissoAgendaSerializer.validate()`), permissão liberada só para "Integração e Inovação" no `seed_portal.py` por ora (mesmo cuidado de sempre: como `calendario-individual` está em `BASE_KEYS`, sem o override todo perfil nasceria podendo criar evento de departamento/todos e cadastrar categoria). Compromissos `"somente_eu"` continuam livres pra qualquer um, sem essa checagem.
- `CategoriaEvento` (`nome` único + `cor` hex, validada por `validar_cor_categoria_evento`) é um cadastro simples via `/api/categorias-evento/` — GET livre a qualquer autenticado (a cor/nome de uma categoria não é sigilosa), escrita restrita à mesma permissão acima. Não é uma lista fixa no código: quem tem a permissão cadastra categorias novas (ex.: "Reunião", "Treinamento") direto no modal de criar/editar compromisso (botão "+" ao lado do `<select>` de categoria, `#ic-event-categoria-add-btn`, que abre `#ic-categoria-modal`) — `seed_portal.py` popula `CATEGORIAS_EVENTO_SEED` como ponto de partida, mas a lista é editável dali em diante.
- `CompromissoAgenda.eh_evento` marca um compromisso como evento formal (não uma reunião pessoal marcada como "todos") — o checkbox correspondente (`#ic-event-eh-evento`, dentro de `#ic-event-eh-evento-field`) só aparece pra quem tem a permissão de criar evento; marcá-lo força a visibilidade pra "Todos" no próprio formulário. `local` (texto livre), `modalidade` (`presencial`/`remoto`/`hibrido`, `<select>` `#ic-event-modalidade`) e `descricao` (texto livre) são campos extras só relevantes pra evento, mas tecnicamente gravam em qualquer compromisso (o formulário só os expõe quando aplicável). No popup somente-leitura (`#ic-view-modal`), cada um aparece como campo próprio (`#ic-view-local-field`/`#ic-view-modalidade-field`/`#ic-view-descricao-field`), escondido (`hidden`) quando vazio — mesmo padrão dos demais campos condicionais desse popup (ver "Pill do compromisso" acima).
- Visualmente, um evento ganha um bucket de cor próprio (`--coral`) tanto no pill do calendário (`.calendar-event--evento`) quanto no chip de filtro "Eventos" — mesmo sendo sempre `visibilidade="todos"` por baixo, não se mistura visualmente com um "Todos" comum (ver parágrafo acima).
**Pill do compromisso: sempre "HH:MM Título", nada mais** — todo pill mostra só horário+título, nunca o nome do dono, pra manter o mesmo formato/tamanho independente da categoria ("simétrico", pedido explícito do usuário; a primeira versão acrescentava "— Nome do dono" direto no texto dos compromissos que não eram do usuário, o que descalibrava o visual porque nomes têm tamanhos bem diferentes). Todo pill é clicável (`cursor:pointer` na classe base `.calendar-event`, não só em `--somente-eu`): se `ev.sou_dono`, abre o modal de edição de sempre (`#ic-modal`, fecha também clicando fora — `event.target === modal`, mesmo padrão de `links-ferramentas.js`/`ramais-lookup.js`); senão, abre um modal novo, só leitura (`#ic-view-modal`/`openViewModal()`, mesmo fecha-ao-clicar-fora), com data/horário por extenso, `dono_nome` (rotulado "Agendado por:", não "Responsável" — mudança de nomenclatura pedida pelo usuário), o rótulo da visibilidade (`PID_IC_VISIBILIDADE_LABELS`, mapeia `ev.visibilidade` pro texto exibido nos chips) e, só quando `ev.visibilidade === "departamento"`, o nome do departamento (`ev.departamento_compartilhado_nome`, campo já vinha do serializer). É esse popup — não o texto do pill — que carrega toda a informação que antes tentava caber na própria pílula.
**Célula do dia com altura fixa, lista de compromissos rolável** (`.calendar-day`/`.calendar-day__events` em `calendario.css`): `.calendar-day` tem `height` fixo (108px desktop, 76px no breakpoint mobile — antes era `min-height`, o que deixava a linha inteira da grade crescer quando um dia tinha muitos compromissos, desalinhando a altura de todas as células daquela semana). Os pills não são mais filhos diretos de `.calendar-day` — `calendar-individual.js` (`render()`) os agrupa num `<div class="calendar-day__events">` (`flex:1; min-height:0; overflow-y:auto`) irmão de `.calendar-day__header`. **`.calendar-day` (o item de grid, não só o `__events` interno) também precisa de `min-height:0` + `overflow:hidden`** — sem isso, o "tamanho mínimo automático" que grid/flexbox calculam por padrão pra um item (baseado no conteúdo, ignorando `height` explícito) ainda fazia a *linha da grade* crescer pra caber todos os pills, mesmo com a célula e o `overflow-y:auto` do `__events` configurados certinho por dentro — o corte real só acontece quando o próprio item de grid para de contribuir com seu min-content pro cálculo da altura da linha (`min-height:0`/`overflow` não-visible fazem isso). Resultado: o cabeçalho (número do dia + botão de adicionar) fica sempre fixo, todas as linhas da grade têm a mesma altura sempre, e uma barra de rolagem aparece dentro da célula só quando os compromissos daquele dia não cabem nos 108px/76px disponíveis.
**Agenda completa do dia** (`#ic-day-modal`, `openDayModal()` em `calendar-individual.js`): clicar no número do dia (`.calendar-day__number`, `cursor:pointer` + destaque no hover) abre um popup com **todos** os compromissos do dia (respeitando os filtros ativos, mesmo `eventosDoDia` usado pra desenhar a célula) mais o feriado, se houver — sem o corte de altura/rolagem da célula, já que o `.day-modal-list` (`calendario.css`) tem `max-height:360px` próprio, bem maior que os 108px da grade, e os pills ali dentro voltam a ter `white-space:normal` (podem quebrar linha) em vez do `nowrap`+ellipsis da grade, então nada aparece cortado. Pra evitar duplicar a criação dos pills em dois lugares (grade e popup), `criarPillCompromisso(ev)`/`criarPillFeriado(iso, nome)` foram extraídas como funções reaproveitadas por `render()` **e** por `openDayModal()` — mesmo elemento, mesmo clique (editar/ver detalhes/ver nome do feriado), só muda o container onde entram. Clicar num item dentro do popup fecha o popup da agenda antes de abrir o modal de destino (edição/visualização/feriado), pra não empilhar dois overlays ao mesmo tempo. O botão "Novo Compromisso" do popup pré-preenche a data com o dia clicado (mesmo mecanismo do "+" de cada célula).
**Feriados no Calendário Individual** (`GET /api/feriados/?ano=AAAA`, `feriados_view` em `views.py`): usa a lib `holidays` (PyPI, `requirements.txt`) pra devolver os feriados **nacionais + estaduais do Paraná** (`holidays.Brazil(years=ano, subdiv="PR", language="pt_BR")`, categoria `public` — o default da lib, exclui pontos facultativos tipo Carnaval/Corpus Christi) do ano pedido, como `[{"data": "AAAA-MM-DD", "nome": "..."}]`. `language="pt_BR"` é passado explicitamente — sem isso, a lib pode cair pro locale do processo do servidor (que nem sempre é pt_BR, ex.: environment com `LANG`/`LANGUAGE` em inglês) em vez do `default_language` da classe `Brazil`, fazendo os nomes virem em inglês ("Independence Day" em vez de "Independência do Brasil") mesmo com o resto do portal em português. **De propósito não tem feriado municipal de Foz do Iguaçu aqui** — nenhuma lib de feriados cobre granularidade de município brasileiro (a `holidays` só tem um caso especial hardcoded pra "São Paulo Capital", nada além disso), e manter uma lista municipal certa exigiria curadoria manual + atualização por decreto da Prefeitura a cada ano; o usuário decidiu deixar de fora por enquanto, só nacional/estadual mesmo. Se algum dia precisar do municipal, a rota certa é o usuário fornecer a lista oficial (decreto da Prefeitura) pra virar uma tabela fixa no código, não tentar adivinhar/inferir datas.
No frontend (`calendar-individual.js`), `carregarFeriados(ano)` busca e cacheia por ano (`Map` em memória, só refaz a requisição ao trocar de ano); `render()` busca também o ano anterior/seguinte quando o mês exibido encosta na borda do ano (janeiro/dezembro), já que os dias "fora do mês" na grade podem pertencer a um ano diferente de `viewYear`. Cada célula de dia feriado ganha a classe `.is-feriado` (fundo tingido de vermelho, `rgba(var(--danger-rgb), 0.1)`) e um pill (`.calendar-day__holiday`, mesmo visual dos pills de compromisso — `.calendar-event`, só que com fundo `--danger` fixo, não uma cor por categoria) com o nome do feriado. Esse pill é irmão de `.calendar-day__header`, **fora** de `.calendar-day__events` — fica sempre fixo no topo da célula, não rola junto com os compromissos do dia. Truncado com `text-overflow:ellipsis` quando o nome não cabe (alguns feriados vêm com dois nomes concatenados por `;`, ex.: "Nossa Senhora do Rocio; Proclamação da República" — ver `feriados_view`); clicar no pill abre `#ic-holiday-modal` (`openHolidayModal()`, mesmo padrão dos outros modais — fecha clicando fora) mostrando a data e o nome completo sem corte. É só informativo, não bloqueia criar/editar compromisso nesse dia.
**Gerente/coordenador vê a agenda individual da equipe**: `CompromissoAgendaViewSet.get_queryset` acrescenta `Q(visibilidade="somente_eu", dono__in=usuario.liderados.all())` às regras de visibilidade — ou seja, além de "todos" e "departamento" (ver acima), quem tem gente em `Usuario.liderados` (ver seção "Liderança") também enxerga os compromissos privados (`"somente_eu"`) de cada liderado, mas sem poder editá-los (`sou_dono` continua `False` pra esses, `CompromissoAgendaViewSet.get_object` já barra escrita de quem não é dono). Não há necessidade de checar `usuario.lideranca` explicitamente na query — `liderados` só é populado através de fluxos que já exigem esse flag (ver "Liderança"), então a cláusula é inofensiva (não casa nada) pra quem não lidera ninguém.
**Lembrete com horário comercial** (`CompromissoAgenda.lembrete_antecedencia`, opcional — `""` = sem lembrete; `"1h"`/`"2h"`/`"4h"`/`"24h"`): não existe nenhum mecanismo de push/e-mail no projeto — o "lembrete" é só o momento a partir do qual o compromisso passa a aparecer no sino de notificações (`notif-bell`), que já era recalculado a cada carregamento de página (sem processo em segundo plano). `CompromissoAgenda.calcular_notificar_em()` (`models.py`) calcula esse horário contando `lembrete_antecedencia` horas **de expediente** (seg-sex, 8h-18h, `COMPROMISSO_HORARIO_COMERCIAL_INICIO`/`_FIM`) pra trás a partir de `data`+`horario` — fora do expediente não conta como antecedência "gasta", só é pulado de graça. Por isso um compromisso às 08h de segunda com lembrete de 4h não notifica às 04h (fora do expediente); o algoritmo (`_janela_comercial`/`_dia_util_anterior`, funções módulo-level) pula pro fechamento do expediente do dia útil anterior (sexta 18h) e só então desconta as 4h, resultando em sexta 14h. Sem `horario` definido no compromisso (evento de dia inteiro) ou sem `lembrete_antecedencia`, não há o que calcular e `calcular_notificar_em()` retorna `None`. O resultado é exposto só leitura via `notificar_em` no serializer (ISO datetime ou `null`); `pidBuildEventNotifications()` (`notifications.js`) só inclui um compromisso na lista do sino quando `notificar_em` não é nulo **e** já foi atingido (`now >= notificar_em`) — compromissos sem lembrete configurado simplesmente não aparecem no sino (comportamento diferente de antes da migração, quando todo compromisso futuro aparecia lá independente de qualquer configuração).
`widgets.js` mantém um registro extensível `PID_WIDGET_TYPES` (`{ "<chave>": { label, description, href, linkLabel, visibleIf? } }`) — hoje existem `"calendario-individual"` e `"links-favoritos"` (ver seção própria abaixo). `href`/`linkLabel` alimentam o link de rodapé do card ("Ver X completo →"); antes de existir um segundo tipo de widget esse link era hardcoded pra `calendario-individual.html`, então ao adicionar um tipo novo **sempre** preencher os dois, senão o rodapé de todos os widgets aponta pro lugar errado. `visibleIf(me)` é opcional — quando presente, filtra o tipo tanto do picker (`renderPicker()`) quanto da grade já adicionada (`renderWidgets()`), usado pra widgets que exponham dado de um módulo com permissão própria (ex.: `links-favoritos` só aparece pra quem tem `apps["links-ferramentas-visualizar"]` em `links-ferramentas`). Para adicionar um novo tipo de widget: registrar a entrada em `PID_WIDGET_TYPES` e adicionar um `case`/`if` em `widgetBodyFor()` que retorne o HTML do corpo do card; o picker (`#widget-picker-modal`) e a grade (`#widgets-grid`) já lidam com adicionar/remover genericamente via `/api/widgets/`.
**Reordenar e redimensionar widgets** (`WidgetUsuario.ordem`/`largura`/`altura`, por usuário): `.widgets-grid` é `display:flex; flex-wrap:wrap` (não mais CSS Grid — precisava permitir que cada `.widget-card` tivesse largura/altura próprias e livres, incompatível com colunas de grid uniformes). Reordenar é drag-and-drop nativo HTML5 igual ao de Links & Ferramentas (`dragstart`/`dragover`/`drop` em `#widgets-grid`, `PATCH /api/widgets/{tipo}/` só nos itens cujo `ordem` mudou) — a diferença é que o `draggable="true"` fica só em `.widget-card__header` (a barra de título), não no card inteiro, pra não conflitar com o handle nativo de resize (`resize: both` em `.widget-card`, ativo no canto inferior direito). Redimensionar usa esse `resize: both` do CSS (sem JS de arraste custom) — um `ResizeObserver` por card (`observeWidgetSizes()`) detecta a mudança de tamanho e salva `largura`/`altura` com debounce de 500ms; como o resize é 100% nativo do browser, não precisa nenhum cálculo manual de arraste. Como o conteúdo de um widget pode ficar maior que o espaço depois de encolhido, só `.widget-card__body` tem `overflow-y: auto` (o cabeçalho e o link de rodapé ficam fixos, só o corpo rola).
## Links & Ferramentas
"Links & Ferramentas" era uma seção do menu com uma única aplicação (a grade de cartões); virou uma seção com **duas** aplicações reais — a grade de cartões original e "Acessos Gerais" (ver seção própria abaixo) — quando essa segunda foi adicionada. Por isso o item do menu, que antes era um link direto (`<li data-section="links-ferramentas"><a href="links-ferramentas.html">`), agora é um `nav-group` expansível (mesmo padrão de "Portais"/"Auditorias") com dois `nav-subitem`: "Links & Ferramentas" (`data-app="links-ferramentas-visualizar"`, mesma URL de antes) e "Acessos Gerais" (`data-app="acessos-gerais-visualizar"`, `acessos-gerais.html`). Isso teve um efeito colateral em `favorites.js`: como o `<li data-section="links-ferramentas">` não tem mais um `<a class="nav-item">` direto (virou um `<button data-group-toggle>`), a seção como um todo deixou de ser favoritável — só os dois sub-itens são, cada um com seu próprio `app_id` derivado (`"links-ferramentas__links-ferramentas"`/`"links-ferramentas__acessos-gerais"`, ver "Favoritos" acima). Um favorito antigo com `app_id === "links-ferramentas"` (de antes dessa mudança) para de casar — mesma categoria de caveat já documentada em "Favoritos": mudar a forma como um item aparece no menu muda o `app_id` derivado.
`LinkFerramenta` é uma lista **global/compartilhada** (sem FK pra `Usuario`, ao contrário de `Favorito`/`WidgetUsuario`/`NotificacaoDispensada`) — todo usuário com `apps["links-ferramentas-visualizar"]=True` em `permissoes["links-ferramentas"]` vê os mesmos cartões via `GET /api/links-ferramentas/` (ver "Padrão visualizar/editar" acima).
`links-ferramentas.js` também gateia o **conteúdo da própria página** por `apps["links-ferramentas-visualizar"]` (`#lf-no-access`/`#lf-content` em `links-ferramentas.html`, mesmo padrão do `.no-access` de `portal.html`) — isso existe porque o sidebar (`data-section="links-ferramentas"` em `access.js`) só esconde o `nav-group` inteiro com base no `enabled` do módulo (e cada sub-item individualmente com base no seu `-visualizar`), então alguém sem `apps["links-ferramentas-visualizar"]` mas que navegue direto pra URL (ou tenha `enabled=true` sem essa flag, uma combinação tecnicamente possível já que são independentes) via GET no backend recebia 403 e via a tela renderizada com "Nenhum link cadastrado ainda." em vez de uma mensagem de acesso negado. Ao adicionar uma aplicação nova no padrão visualizar/editar, replicar esse gate (como `acessos-gerais.js` já faz) — não basta confiar em `access.js` escondendo o link do menu.
Só quem tem `apps["links-ferramentas-editar"]=True` (`me.permissoes_efetivas["links-ferramentas"].apps["links-ferramentas-editar"]`, já unido no servidor) vê em `links-ferramentas.html` os controles de administração: botão "Adicionar Link" no topo e, em cada cartão, setas de mover para cima/baixo + X de remover (`links-ferramentas.js`, gated no frontend por essa flag, e reforçado no servidor por `PermissaoApp("links-ferramentas", "links-ferramentas-editar")`/`PermissaoApp("links-ferramentas", "links-ferramentas-visualizar")` conforme o método HTTP).
- **Ordenação**: campo `ordem` (inteiro, sem `unique`) em `LinkFerramenta`, `Meta.ordering = ["ordem", "id"]`. Não existe endpoint de reorder em lote no backend — o cliente é quem decide quais `PATCH`es disparar. Duas formas de reordenar na UI, ambas em `links-ferramentas.js`: as setas (`swapOrdem()`) trocam o `ordem` de dois itens adjacentes com duas chamadas `PATCH`; arrastar um cartão (drag-and-drop nativo HTML5, `.lf-card--draggable`/`dragstart`/`dragover`/`drop` no `#lf-grid`) recalcula a lista inteira em memória e envia um `PATCH` só para os itens cujo `ordem` (índice na nova ordem) realmente mudou — como não há `unique` em `ordem`, não tem problema disparar essas chamadas em paralelo (`Promise.all`) mesmo que dois itens fiquem com o mesmo valor por um instante. Ao criar um link novo, o servidor sempre calcula `ordem = max(ordem atual) + 1` em `LinkFerramentaViewSet.perform_create` — qualquer `ordem` enviada pelo cliente no POST é ignorada.
- **Ícone**: `icone` é um `ImageField` opcional (upload real, não URL) — exige Pillow (`requirements.txt`) e `MEDIA_URL`/`MEDIA_ROOT` (`settings.py`, servido em `DEBUG` por `config/urls.py`). Sem ícone, o cartão cai num SVG de fallback (`PID_LINK_DEFAULT_ICON` em `links-ferramentas.js`, mesmo glifo do item "Links & Ferramentas" no menu). O upload viaja como `multipart/form-data` (`FormData`), não JSON — ver a nota sobre `pidApiRequest` acima. Limite de tamanho: **2MB**, checado em dois lugares — `validar_tamanho_icone_link` (validator do campo `icone` em `models.py`, é a checagem que vale de verdade, roda via `LinkFerramentaSerializer.is_valid()`) e uma checagem espelhada em `links-ferramentas.js` (`PID_LINK_ICON_MAX_BYTES`, no `change` do input e de novo antes do POST/PATCH) só para dar feedback sem esperar a resposta do servidor. Ao mudar o limite, atualizar os dois lados (e gerar migração — `validators` no campo entra no `deconstruct()`).
- Clicar num cartão sempre abre a URL numa aba nova (`target="_blank"`) — são links externos por definição, não faz sentido navegar embutido no portal.
- Editar um cartão existente (nome, URL e ícone) usa o mesmo modal de "Adicionar Link" (`#lf-add-modal`), reaproveitado em modo edição — o botão de lápis em cada cartão (visível só com `apps["links-ferramentas-editar"]`, ao lado das setas de mover) chama `openModal(link)` pré-preenchendo os campos; salvar despacha `PATCH /api/links-ferramentas/{id}/` (`pidUpdateLink`, multipart igual ao POST) em vez de criar um novo. O campo de ícone fica sempre vazio ao abrir em modo edição (input `type="file"` não aceita valor pré-preenchido por segurança do browser) — não enviar o campo `icone` no PATCH mantém o ícone atual; só enviar substitui.
- **Favoritos por link** (`LinkFerramentaFavorito`, model dedicado — não confundir com `Favorito`, que marca aplicações inteiras do menu): estrela em cada cartão (`.lf-card__favorite`, visível pra qualquer um com `apps["links-ferramentas-visualizar"]`, independente de editar) via `POST`/`DELETE /api/links-ferramentas-favoritos/{link_id}/` (natural key é o `id` do link, igual ao padrão `app_id`/`notif_id` de `Favorito`/`NotificacaoDispensada`). Só afeta a **ordem de exibição dentro da própria tela** — `links-ferramentas.js` busca `links` e favoritos em paralelo e reordena em memória (`sortFavoritesFirst()`) pra mostrar favoritos primeiro, preservando o `ordem` relativo dentro de cada grupo; o `ordem` compartilhado do `LinkFerramenta` nunca é tocado por favoritar/desfavoritar. Simplificação deliberada: as setas de mover e o drag-and-drop operam sobre esse mesmo array já reordenado (`links`), então se um usuário com `apps["links-ferramentas-editar"]` também tiver favoritos marcados, arrastar um cartão persiste a ordem "favoritos primeiro" que ele está vendo como o novo `ordem` compartilhado — aceitável pro tamanho do app, mas vale lembrar se o comportamento parecer estranho.
- **Widget "Links Favoritos"** (`links-favoritos` em `PID_WIDGET_TYPES`, `static/js/widgets.js`): lista em `portal.html` só os links favoritados, cada linha com ícone pequeno (`.widget-links-list__icon`, fallback `PID_WIDGET_LINK_DEFAULT_ICON` — cópia local do glifo de `PID_LINK_DEFAULT_ICON`, já que `widgets.css` não carrega `links-ferramentas.css`) + nome, a linha inteira é um `<a target="_blank">` pro mesmo destino do cartão original. Depende de `pidFetchLinks`/`pidFetchLinkFavoritos`, então `links-ferramentas.js` foi incluído em `portal.html` só por causa dessas funções de dados — seu handler de `DOMContentLoaded` retorna cedo lá (`if (!grid) return`, não existe `#lf-grid` em `portal.html`), mesmo padrão de guarda de `profiles.js`/`widgets.js`.
## Acessos Gerais
Segunda aplicação da seção "Links & Ferramentas" (ver acima) — um cadastro de acessos/logins compartilhados (ex.: "login geral de um site"), organizado em **seções e linhas** (inspirado numa tela do Asana que o usuário mostrou como referência): cada seção agrupa várias linhas, e clicar numa linha abre um popup com os detalhes daquele acesso. Dois models novos, sem relação com `LinkFerramenta`:
- `AcessoGeralSecao` (`nome`, `ordem`, `perfis_restritos` M2M pra `PerfilAcesso`, ver abaixo) — só a categoria (ex.: "Banco de Dados/API"). Lista compartilhada, sem FK pra `Usuario`.
- `AcessoGeral` (`secao` FK, `nome`, `url`, `usuario`, `senha`, `observacoes`, `ordem`) — a linha em si. `senha` é um `CharField` em texto puro (não há criptografia/hash — é um cadastro de referência entre a própria equipe, não um cofre de senhas robusto; se isso precisar mudar no futuro, confirmar com o usuário antes, já que envolve infraestrutura de chave/criptografia nova). `observacoes` guarda **HTML sanitizado** (ver "Observações ricas" abaixo), com um `validators=[validar_tamanho_observacoes_acesso]` (`models.py`) limitando a 2.000.000 caracteres — generoso o bastante pra várias imagens embutidas, mas evita um `TextField` sem limite nenhum crescer sem controle.
**Permissão**: mesmo padrão visualizar/editar de Links & Ferramentas, com chaves próprias (`acessos-gerais-visualizar`/`acessos-gerais-editar`, ver "Padrão visualizar/editar" acima) — `AcessoGeralSecaoViewSet`/`AcessoGeralViewSet` (`views.py`) instanciam `PermissaoApp("links-ferramentas", app_key)` com a chave certa por método HTTP. `acessos-gerais.js` gateia o conteúdo da própria página (`#ag-no-access`/`#ag-content`) por `acessos-gerais-visualizar`, mesmo raciocínio do gate de `links-ferramentas.js`.
**Restrição de seção por perfil** (`AcessoGeralSecao.perfis_restritos`): além da permissão de módulo, cada seção pode opcionalmente ser restrita a um subconjunto de `PerfilAcesso` — `perfis_restritos` vazio (padrão) = visível a qualquer um com `acessos-gerais-visualizar`; não vazio = só quem também tiver um desses perfis vinculado. Isso é uma restrição de **dado**, independente da árvore de permissões (não precisa mexer em Perfis de Acesso pra configurar) — é escolhida direto no modal "Adicionar Seção"/"Renomear Seção" (`#ag-secao-form-perfis`, um `.checklist-box` com todos os perfis cadastrados, populado via `pidFetchPerfis()`). O filtro é aplicado em dois lugares no backend, ambos em `views.py`:
- `AcessoGeralSecaoViewSet.get_queryset()` — só devolve seções sem restrição ou com interseção entre `perfis_restritos` e os perfis do usuário logado; `AcessoGeralViewSet.get_queryset()` aplica o mesmo filtro via `secao__perfis_restritos`, pra uma linha nunca vazar de uma seção que o usuário não veria.
- `AcessoGeralSerializer.__init__` também restringe o próprio campo `secao` (o `PrimaryKeyRelatedField` que valida o POST/PATCH) à mesma queryset filtrada — sem isso, alguém com `acessos-gerais-editar` mas sem o perfil exigido conseguiria criar uma linha dentro de uma seção restrita só sabendo o id dela, mesmo sem enxergá-la em nenhuma listagem.
Não há exceção pra `gerencia_permissoes`/perfil de acesso total — mesmo "Integração e Inovação" (código 8) fica de fora de uma seção restrita a outro perfil que não o seu, exatamente como qualquer outro perfil (é uma lista de permissão explícita, não um nível hierárquico).
**Ordenação por seção**: `AcessoGeral.ordem` é **escopada por `secao`** (ao contrário de `LinkFerramenta.ordem`, que é global) — `AcessoGeralViewSet.perform_create` calcula `max(ordem)` só entre as linhas da mesma seção. Reordenar (drag-and-drop nativo HTML5, mesma mecânica de `links-ferramentas.js` — `dragstart`/`dragover`/`drop` em `#ag-sections`, delegado num container que tem todas as seções) só é permitido **dentro de uma seção**: `dragover` ignora o alvo se `draggedAcesso.secao !== targetAcesso.secao`, então uma linha nunca muda de seção arrastando. As setas de mover para cima/baixo (`swapOrdem()`) seguem a mesma regra, já que operam sobre `acessosDaSecao(secao.id)`, nunca a lista inteira. Seções em si não têm drag-and-drop — só criar/renomear/excluir; a ordem entre seções é a de criação (`ordem` incrementado pelo servidor, sem UI de reordenar).
**Observações ricas (texto + imagens embutidas)**: o campo "Observações" do modal de acesso (`#ag-form-observacoes`) é um `<div contenteditable>`, não um `<textarea>` — permite formatar texto livremente e incluir imagens **sem nenhum botão dedicado**: colar (`Ctrl+V`, evento `paste`, lido de `event.clipboardData.items`) ou arrastar um arquivo de imagem pra dentro do campo (evento `drop`, com `dragover` chamando `preventDefault()` pra permitir o drop) — as duas vias caem na mesma função `insertImageFile()` em `acessos-gerais.js`. A imagem (até **2MB**, `PID_AG_IMAGE_MAX_BYTES`, checado antes de inserir) vira uma data URI via `FileReader.readAsDataURL` e é inserida com `document.execCommand("insertImage", ...)` — sem upload de arquivo separado, fica embutida no próprio HTML salvo em `observacoes`. No caminho de `paste` o cursor já está na posição certa (o navegador só troca o clipboard, não move o foco); no de `drop`, `placeCaretAtPoint()` usa `document.caretRangeFromPoint`/`caretPositionFromPoint` (conforme suporte do browser) pra posicionar o cursor exatamente onde o arquivo foi solto antes de inserir.
- **Sanitização (`nh3`)**: como esse HTML é gerado por quem tem `acessos-gerais-editar` mas renderizado via `innerHTML` pra qualquer um com `acessos-gerais-visualizar`, ele passa por um allowlist estrito no backend antes de salvar — `AcessoGeralSerializer.validate_observacoes()` roda `nh3.clean()` permitindo apenas tags de texto básicas + `<img>` (`ACESSO_GERAL_OBSERVACOES_ALLOWED_TAGS`/`_ALLOWED_ATTRS`/`_ALLOWED_SCHEMES` no topo de `serializers.py`) — **sem `<a>`/`<script>`/atributos de evento** (`onerror` etc. são descartados por não estarem na allowlist de atributos). `url_schemes` inclui `"data"` de propósito, já que as imagens embutidas são `data:image/...;base64,...`, não URLs externas. Isso significa que o campo é reprocessado no servidor mesmo que o cliente já não deixe inserir nada além de texto/imagem pela UI — defesa em profundidade contra alguém montando o payload na mão. `nh3` é o binding Python da lib Rust "ammonia" (`requirements.txt`) — foi escolhido no lugar do `bleach` (usado numa primeira versão desta funcionalidade) porque o `bleach` está oficialmente sem manutenção desde 2023 e parou de receber releases (inclusive de segurança) em 2026; `nh3` tem API quase idêntica (`clean(html, tags=set[...], attributes=dict[...], url_schemes=set[...])`, allowlist do mesmo jeito) e é o substituto recomendado pelos próprios mantenedores do bleach.
- Ao carregar um acesso existente pra editar, `formObservacoes.innerHTML = acesso.observacoes` repopula o editor com o HTML já sanitizado (imagens inclusas); salvar lê `formObservacoes.innerHTML` (função `observacoesValue()`, que retorna string vazia se não houver nem texto nem `<img>`, evitando salvar lixo tipo um `<br>` solto de um editor "vazio").
**Popup de detalhes** (`#ag-view-modal`, `acessos-gerais.js`): mostra nome, URL (link clicável), usuário, senha e observações — cada campo (`.ag-view-field`) só aparece se tiver valor (`hidden` quando vazio). A senha começa mascarada (`"••••••••"`, com o valor real guardado em `viewSenha.dataset.value`) e um botão de olho alterna pra o valor real — a máscara é feita trocando o próprio `textContent`, não com CSS (`-webkit-text-security` não é suportado em todos os browsers e deixaria a senha real exposta no DOM seletável mesmo "mascarada" visualmente nesses casos). As observações são renderizadas via `innerHTML` (não `textContent`, ao contrário dos outros campos) já que podem conter as imagens embutidas — seguro porque o HTML já veio sanitizado do backend; o container é uma `<div class="ag-view-observacoes">` (não `<p>`, que não pode conter `<img>`/`<div>` sem gerar HTML inválido). Com `acessos-gerais-editar`, o popup também mostra "Editar"/"Excluir"; "Editar" fecha o popup e abre o mesmo modal de formulário (`#ag-form-modal`) usado por "Adicionar Acesso", pré-preenchido.
Nenhuma tela recalcula união de departamentos/liderança aqui — é uma aplicação isolada, sem relação com `Usuario` além da permissão de quem pode ver/editar (e, agora, do `perfis_restritos` por seção).
## Ramais
O diretório de `ramais.html` é **automático**: `RamalViewSet.list()` (não o `RamalSerializer` — esse serializer só cobre as linhas avulsas via CRUD normal) mescla, a cada `GET /api/ramais/`, duas fontes numa lista só, ordenada por nome:
1. Todo `Usuario` ativo — a linha é montada direto do cadastro (`nome`, `Usuario.departamentos` juntados por vírgula, `Usuario.ramal`); se o colaborador ainda não tem ramal preenchido, `numero_exibicao` vem vazio e o frontend mostra um badge "Pendente" em vez de reclamar de campo faltando.
2. As linhas avulsas de `Ramal` (sem `Usuario` por trás — telefone de sala, recepção etc.), cadastradas pelo modal "Adicionar Ramal".
Cada item da lista mesclada tem um `id` sintético (`"usuario-<id>"` ou `"avulso-<id>"`) e um campo `tipo` (`"usuario"`/`"avulso"`) que o frontend usa pra decidir qual endpoint chamar ao editar/excluir — não existe mais um model unificando os dois casos com uma FK opcional (essa foi a primeira versão da tela; revertida a pedido do usuário pra eliminar o passo manual de "adicionar" alguém que já tem cadastro).
Segue o mesmo padrão visualizar/editar de Links & Ferramentas (ver acima): leitura exige `apps.visualizar` (liberado a todo perfil, já que `ramais` está em `BASE_KEYS`), escrita exige `apps.editar` — por ora só `True` pra "Integração e Inovação" no `seed_portal.py`, exatamente como pedido; liberar outro perfil não pede código novo, só marcar o app na árvore de Perfis de Acesso.
- **Editar o ramal de um colaborador de verdade**: não existe "criar" — a linha já aparece sozinha. O lápis na linha abre o mesmo modal de Ramal, mas com Nome/Departamento desabilitados (só leitura do cadastro) e só o campo Ramal editável; salvar chama `PATCH /api/ramais/usuarios/{usuario_id}/` (`RamalViewSet.atualizar_ramal_usuario`), que grava direto em `Usuario.ramal` — é assim que a tela demonstra a alteração refletindo no cadastro do usuário.
- **Linha avulsa**: "Adicionar Ramal" sempre cria uma linha avulsa (`POST /api/ramais/`, `nome`/`departamento`/`numero` livres — só `nome` é obrigatório, o resto pode ficar pendente igual a um colaborador de verdade). Editar/excluir uma linha avulsa usa `PATCH`/`DELETE /api/ramais/{avulso_id}/` normalmente; excluir só existe pra esse tipo (não dá pra "excluir" um colaborador daqui — isso é na tela de Usuários).
- **Lista de usuários do modal de Ausência**: `RamalViewSet.usuarios_disponiveis` (`GET /api/ramais/usuarios/`) devolve só `id`/`nome` de usuários ativos, pra alimentar o `<select>` "Lista de Usuários" do modal "Criar Ausência" (o único modal que ainda precisa escolher uma pessoa numa lista — o modal de Ramal não precisa mais, já que a linha do colaborador já existe). Não reaproveita `/api/usuarios/` de propósito — aquele endpoint é restrito a `gerencia_permissoes`, e a permissão de Ramais é deliberadamente desacoplada disso (hoje dá na mesma pessoa, mas não presume que sempre será assim).
- **Ausência** (`RamalAusencia`): um registro por período criado pelo modal "Criar Ausência"; "ausente agora" nunca é armazenado — `RamalAusencia.esta_ativa()` compara a hora atual (`timezone.localtime()`) contra `[data_inicio+hora_inicio, data_fim+hora_volta]` (hora ausente = considera o dia inteiro) toda vez que `RamalViewSet.list()` monta a resposta. Clicar no badge "(AUSENTE)" de uma linha (`data-ram-ver-ausencia`, qualquer um com `apps.visualizar` pode abrir) faz `GET /api/ramais-ausencias/{id}/` e abre o modal "Visualizar Ausência" — campos desabilitados (`<input type="date"/"time">` mostra a data/hora formatada mesmo `disabled`, sem precisar formatar manualmente), com "Editar Ausência"/"Deletar Ausência" visíveis só pra quem tem `apps.editar`. "Editar" habilita os mesmos campos in-place (sem modal novo) e troca os botões por "Cancelar"/"Salvar Ausência" (`PATCH /api/ramais-ausencias/{id}/`); "Deletar" remove o registro (`DELETE`) — não existe mais um botão de "encerrar antes do previsto" separado (a rodada anterior tinha isso via `encerrada_manualmente`; substituído por editar/excluir de verdade, mais simples e é o que foi pedido). O campo `encerrada_manualmente` continua no model (histórico/uso futuro via admin), só não tem mais UI própria.
- **Aniversariante**: comparação de `Usuario.data_aniversario` (mês/dia) com `timezone.localdate()`, feita no mesmo `list()` — mesmo campo que já existia no cadastro de Usuários, sem nada novo ali.
- **Selos de ausente/aniversariante**: `.ram-badge--ausente`/`.ram-badge--aniversario` (`ramais.css`) são selos (pill) com cor de texto/fundo ajustada por tema via `:root[data-theme="light"] .ram-badge--*` — não reaproveitam `--danger`/`--gold` crus porque esses tokens não foram pensados pra texto pequeno sobre um selo (contraste insuficiente). A linha inteira também é tingida (`.ram-row--ausente`/`.ram-row--aniversario` td, aplicado via classe no `<tr>` em `ramais.js`) com a mesma cor do selo, também ajustada por tema — pedido explícito do usuário pra facilitar notar a linha antes mesmo de ler o selo (a versão anterior sem tingimento de linha foi revertida).
- **Férias**: a aba existe (navegação por abas, ver abaixo) mas está **vazia de propósito** — o conteúdo foi adiado pra uma rodada futura; a limitação original ("depende de integração futura com outro banco") continua valendo, só a decisão de já reservar o espaço na navegação é nova.
- **Novo Chamado**: botão que abre um modal com um `<iframe>` apontando para a ferramenta externa de chamados (`https://depaula-tvcorporativa.lovable.app/chamar?token=...`) — decisão explícita de ficar embutido na própria tela em vez de nova aba (diferente do padrão dos demais links externos do portal). O `src` do iframe só é setado na abertura do modal e volta pra `about:blank` ao fechar, pra não deixar a ferramenta carregada em segundo plano.
- **Sem reordenação**: ao contrário de Links & Ferramentas/Widgets, a listagem é sempre alfabética (`sort()` em `list()`), sem `ordem`/drag-and-drop.
- Usuário inativo (`is_active=False`) não aparece mais no diretório (o `list()` filtra `Usuario.objects.filter(is_active=True)`) — diferença deliberada da primeira versão, que ainda mostrava inativos se tivessem uma linha vinculada.
### Navegação por abas em `ramais.html` (subtelas)
`ramais.html` deixou de ser uma tela única — é uma seção com 5 subtelas, navegáveis por abas logo abaixo do cabeçalho: **Ramais** (diretório descrito acima, ativa por padrão), **Responsável no Tareffa** (placeholder vazio), **Telefones Externos**, **Férias** (placeholder vazio) e **Funções de Telefonia**. As abas reaproveitam o CSS genérico `.pa-tabs`/`.pa-tab`/`.pa-tab-panel` (`perfis-acesso.css`, já carregado nesta página desde antes — mesmo padrão usado nas abas Permissões/Usuários de `perfis-acesso.html`), mas com atributos próprios (`data-ram-tab`/`data-ram-tab-panel`) e uma implementação independente em `ramais.js` (`activeRamTab`/`renderRamTabs()`), pra não colidir com `profiles.js`. Os botões "Adicionar Ramal"/"Novo Chamado"/"Criar Ausência" continuam só dentro do painel "Ramais" — cada subtela tem suas próprias ações.
**Permissão — uma dupla visualizar/(editar) por subtela**: cada uma das 5 abas tem sua própria permissão de visualização, e as 3 com conteúdo administrável (Ramais, Telefones Externos, Funções de Telefonia) também têm sua própria permissão de edição — não é mais um único par genérico `ramais.apps.visualizar`/`ramais.apps.editar` cobrindo tudo (esse desenho, usado na primeira versão da navegação por abas, foi revisto no mesmo dia a pedido do usuário: "deve haver permissão de visualização para cada um dos itens e edição para as de ramais, telefone externos e funções de telefonia"). Em `catalogo.MODULE_APPS["ramais"]`, isso é modelado como **5 subgrupos** (mesmo formato `{"key", "label", "tools": [...]}` já usado em Auditorias — reaproveita 100% a árvore de permissões genérica de `profiles.js`, sem UI nova):
```python
"ramais": [
{"key": "ramais-diretorio", "label": "Ramais", "tools": [
{"key": "ramais-visualizar", "label": "Visualizar"},
{"key": "ramais-editar", "label": "Editar (...)"},
]},
{"key": "responsavel-tareffa", "label": "Responsável no Tareffa", "tools": [
{"key": "responsavel-tareffa-visualizar", "label": "Visualizar"},
]},
{"key": "telefones-externos", "label": "Telefones Externos", "tools": [...]},
{"key": "ferias", "label": "Férias", "tools": [{"key": "ferias-visualizar", ...}]},
{"key": "funcoes-telefonia", "label": "Funções de Telefonia", "tools": [...]},
],
```
Cada `ModelViewSet` (`RamalViewSet`/`RamalAusenciaViewSet`, `TelefoneExternoViewSet`, `FuncaoTelefoniaViewSet`) instancia `PermissaoApp("ramais", app_key)` com a chave da própria subtela (ex.: `"telefones-externos-visualizar"`/`"telefones-externos-editar"`) — `RamalAusenciaViewSet` usa as mesmas chaves `ramais-visualizar`/`ramais-editar` do diretório de Ramais, já que ausência é parte dessa subtela, não uma quinta. No frontend, `ramais.js` calcula um `canView`/`canManage` por subtela a partir de `me.permissoes_efetivas.ramais.apps[chave]`, esconde (`hidden`) o botão de cada aba cujo `visualizar` for falso, e escolhe a primeira aba visível como ativa por padrão (em vez de sempre abrir em "Ramais", que pode estar oculta pra esse perfil). `ramais-lookup.js` (modal de consulta rápida no topbar) usa especificamente `ramais-visualizar`, já que só mostra o diretório de Ramais, não as outras subtelas.
**Cuidado com `seed_portal.py`** (mesmo princípio da nota geral em "Padrão visualizar/editar" acima): como `ramais` está em `BASE_KEYS`, `permissions_from_keys()` habilitaria os 8 apps (visualizar de todas as 5 + editar das 3) de uma vez — sem o override, todo perfil nasceria podendo editar. Por isso `seed_portal.py` força `ramais-editar`/`telefones-externos-editar`/`funcoes-telefonia-editar` para `False` explicitamente em todo perfil que não seja "Integração e Inovação", depois de montar o dict — os `*-visualizar` ficam `True` pra todo mundo de propósito ("os demais terão acesso para visualizar todas"). Qualquer mudança de nome/adição de subtela nesse padrão precisa replicar esse mesmo cuidado.
Um perfil só-visualizar vê as 5 abas e as tabelas, mas nunca os botões de Adicionar/editar/excluir em nenhuma delas; um perfil sem `visualizar` numa subtela específica não vê nem a aba dela.
**Telefones Externos** (`TelefoneExterno`, model dedicado sem FK — contatos de fornecedores/terceiros, não de `Usuario`): CRUD simples via `/api/telefones-externos/`, só `nome` obrigatório (`ramal`/`telefone`/`observacoes` opcionais, mesmo padrão de `Ramal` avulso). Dois filtros de busca (`ram-tel-search-nome`/`ram-tel-search-obs`, client-side sobre o array já carregado) — por nome e por observações, ao mesmo tempo, sem OR/AND configurável. A tabela começa vazia (nenhum seed) — o usuário cadastra pela própria tela.
**Funções de Telefonia** (`FuncaoTelefonia`) — comandos padrão da central telefônica (ex.: `*01 + Código de Agente` → LogOn). CRUD via `/api/funcoes-telefonia/`, só `comando` obrigatório. `Meta.ordering = ["comando"]` reproduz sozinho a ordem esperada (`*0, *01, ..., *5, *503, *8`) porque os códigos já nascem em ordem lexicográfica como string — não precisou de um campo `ordem` manual nem de endpoint de reorder, ao contrário de `LinkFerramenta`/`Favorito`/`WidgetUsuario`. Ao contrário de Telefones Externos, esta tabela **é seedada**: `seed_portal.py` popula as 13 linhas padrão (`FUNCOES_TELEFONIA_SEED`, `update_or_create` por `comando`) porque é documentação genérica de central telefônica, não dado específico da empresa — reexecutar `seed_portal` é seguro/idempotente, não duplica nem apaga linhas editadas manualmente (só atualiza `funcao`/`resumo` de um `comando` que já exista).
Nenhuma das duas subtelas tem endpoint de reorder — só criar/editar/excluir, mesmo escopo pedido.
### Modal de consulta rápida ("Ramais")
O botão "Ramais" do topbar (`#ramais-btn`, presente em `portal.html`/`links-ferramentas.html`/`calendario-individual.html` — as únicas 3 páginas que têm esse atalho; texto era "Acessar Ramais", encurtado depois) **não navega** para `ramais.html`; abre um modal somente-leitura (`ramais-lookup.js`/`ramais-lookup.css`) com a mesma listagem mesclada de `GET /api/ramais/`, inspirado numa tela do portal antigo (estilo DataTables: "Mostrar N registros", busca, colunas ordenáveis, paginação). Diferenças pro comportamento antigo do botão:
- Gate de acesso: some (`hidden`) se `permissoes_efetivas.ramais.apps["ramais-visualizar"]` for falso — mesmo padrão de qualquer UI gated por permissão no app.
- Busca é **uma só caixa** (não uma por coluna) que filtra por nome, departamento ou ramal ao mesmo tempo — mais simples que a paginação em duas caixas da própria `ramais.html`.
- **Botões de filtro por departamento** (`.ram-lookup-depto-filters`, acima da tabela): "Todos" + um botão por `Departamento` cadastrado, buscados de `GET /api/departamentos-resumo/` na primeira abertura (endpoint dedicado, `IsAuthenticated` + checagem manual de `permissao_app("ramais", "ramais-visualizar")` — não reaproveita `/api/departamentos/`, que exige `gerencia_permissoes` e bloquearia a maioria dos usuários que só têm acesso ao próprio Ramais). Clicar num botão filtra a listagem pra quem tem aquele departamento entre os seus (`departamento_exibicao.split(",")`, comparação exata após `trim` — não substring, pra não casar um departamento que seja prefixo de outro) e combina com a busca por texto (as duas condições precisam bater). Como os botões são gerados a partir da lista de departamentos vinda da API a cada abertura do modal, cadastrar um departamento novo em Usuários já basta pra ele aparecer aqui — não precisa mexer no frontend.
- Ordenação por coluna (clicar no cabeçalho alterna asc/desc) e paginação (`10`/`25`/`50`/`100` por página) são só client-side, sobre o array já carregado — sem endpoint novo, sem parâmetro de query; os `/api/ramais/`/`/api/departamentos-resumo/` são buscados uma única vez por abertura de página (cacheados em memória enquanto a página não recarrega) e refiltrados/reordenados em JS a cada tecla/clique.
- Botão "Ir para Controle de Ramais" no rodapé é o link de verdade pra `ramais.html` (tela completa, com edição) — o modal em si não tem nenhum controle de escrita, é só consulta.
## Solicitações
Os 6 tópicos do menu "Solicitações" (`catalogo.MODULE_APPS["solicitacoes"]`) não são telas próprias — cada um (exceto "Ordem de Serviço", que ainda não tem link definido e continua com `href="#"`, mesmo padrão de qualquer aplicação-placeholder do portal) é só um link externo (hoje, um formulário do Asana) aberto em **nova aba** (`target="_blank" rel="noopener noreferrer"`), igual ao padrão já usado nos cartões de Links & Ferramentas.
**Por que não embutido em iframe**: a primeira versão desta seção tentava centralizar os 5 links num popup com `<iframe>` (numa página dedicada `solicitacoes.html`), inspirado no "Novo Chamado" de Ramais. Revertido no mesmo dia: o Asana bloqueia ser carregado em iframe de outro domínio via `X-Frame-Options`/`Content-Security-Policy: frame-ancestors` (proteção padrão contra clickjacking), então o navegador recusa a conexão (`net::ERR_BLOCKED_BY_RESPONSE`/"A conexão com form.asana.com foi recusada"). Isso não tem workaround no frontend — não confundir com o iframe de "Novo Chamado" em Ramais ou o de "Calendário De Paula" (ver nota logo após a tabela de páginas, em "Páginas" acima), que funcionam porque aquela outra ferramenta (`depaula-tvcorporativa.lovable.app`) não bloqueia embed. Não reintroduzir esse padrão de iframe pra Solicitações sem confirmar com o usuário que o destino realmente permite ser embutido.
## Simulação de Custo de Contratação (Geradoc)
Ferramenta que substitui a planilha manual de custo de contratação (`projects/planilha de custo/*.xlsx`) por um formulário no Portal — calcula o custo de contratar um Empregado CLT e devolve um PDF pronto pra enviar ao cliente. Permissão de **toggle único** (`apps["simulacao-custo-contratacao"]` em `permissoes["geradoc"]`, sem par visualizar/editar), checada manualmente (`request.user.permissao_app("geradoc", "simulacao-custo-contratacao")`) nas duas views (não são `ModelViewSet` — são funções simples, `POST /api/simulacao-custo-contratacao/gerar/` e `GET`/`PATCH /api/parametros-fiscais-custo-contratacao/`).
- **Escopo v1: só Empregado CLT.** O pedido original mencionava 5 modalidades (Simples Nacional, Regime Normal, Pró-labore, Empregado, Empregado Doméstico), mas só havia planilha de referência validada pra Empregado CLT — as outras 4 ficam para quando houver uma fonte de regras equivalente confirmada pelo contador; não implementar "seguindo o mesmo padrão" por conta própria.
- **Sem persistência**: `POST /api/simulacao-custo-contratacao/gerar/` é um cálculo pontual — recebe os dados do formulário, calcula (`custo_contratacao.calculo.calcula_custo_empregado`) e devolve o PDF direto (`HttpResponse` binário, `Content-Disposition: inline`), nada é salvo no banco. Diferente do padrão "com histórico" de `ImportacaoPlanoSaude`/`IndicadorApuracao`.
- **Tabelas de INSS/IRRF editáveis pelo banco**: `ParametroFiscalCustoContratacao` (`models.py`) é um singleton (`atual()`, sempre `pk=1`, criado sob demanda via `get_or_create`) com `faixas_inss`/`faixas_irrf` em `JSONField` (lista de `{limite_superior, aliquota, deduzir}`) + escalares (teto de desconto de INSS, alíquota/dedução do IRRF acima da última faixa, desconto simplificado do IRRF, dedução por dependente, e os 3 parâmetros da redução da Lei 15.270/2025 — coeficientes A/B e limite de rendimento bruto), editáveis pelo painel colapsável da própria tela (`GET`/`PATCH /api/parametros-fiscais-custo-contratacao/`, mesma permissão de quem usa a simulação). `custo_contratacao/tabelas.py` continua existindo só como **seed/default** da primeira criação da linha (`_faixas_inss_padrao`/`_faixas_irrf_padrao` em `models.py`) — `calculo.py` nunca lê `tabelas.py` direto, sempre recebe um `ParametrosFiscais` (dataclass pura, sem ORM) montado por `ParametroFiscalCustoContratacao.para_calculo()`.
- **Redução de IRRF da Lei nº 15.270/2025** (art. 3º-A da Lei 9.250/1995, vigente desde jan/2026): isenção total até R$5.000 de rendimento bruto mensal, redução decrescente até zerar em R$7.350 — `redução = max(0, coeficiente_a − coeficiente_b × rendimento bruto)`, aplicada por cima do imposto já calculado pela tabela progressiva tradicional (que a lei não alterou), nunca deixando o imposto final negativo.
- **Correção deliberada em relação à planilha original**: a planilha nunca somava a dedução por dependente (R$189,59/dependente) à base do IRRF quando usava o desconto real de INSS — só quando usava o desconto simplificado (que por lei substitui os dois). Confirmado como gap com o usuário e corrigido: ao usar o desconto real de INSS, a dedução por dependente também é subtraída agora (`custo_contratacao/calculo.py`).
- **PDF via `reportlab`** (pure-Python, sem dependência nativa problemática no Windows) — cabeçalho é um banner marrom escuro com `logo-branco.png` + "De Paula Contadores", nas cores reais da marca (dourado `#D3AF4D`, marrom `#4A3C28`, amostradas do próprio `logo.png`), não o roxo do tema de interface do Portal.
- Localização no menu (dentro de **Geradoc**, ao lado de "Gerar Contrato"/"Gerar Procuração") foi escolha explícita do usuário, não Utilitários.
## Indicador de Desempenho (Geradoc)
Segunda ferramenta de Geradoc — substitui a apuração manual do indicador de desempenho do Fiscontábil (departamentos Contábil/Fiscal), antes feita numa planilha (`FISCO CONTABIL *.ods`, em `projects/Indicadores/`) com fórmulas quebradas por edições manuais acumuladas. Mesmo padrão de permissão de **toggle único** de Simulação de Custo de Contratação (`apps["indicador-desempenho"]` em `permissoes["geradoc"]`, checado por `PermissaoApp("geradoc", "indicador-desempenho")` em todos os `ModelViewSet` relacionados). Pacote de negócio em `portal_api/indicadores/` (sem ORM): `tipos.py`, `leiaute.py`, `pipeline.py`, `entregas.py`, `calculo.py`, `recibo.py`, `departamentos.py`.
- **Escopo v1: só o Fiscontábil**, papéis Balancete/Liberação Fiscal/Conciliação Financeira. Outros departamentos ficam pra rodada futura — **exceto pela estrutura de cadastro em si** (ver "Departamento organizacional" abaixo), que já suporta múltiplos departamentos com critérios/percentuais próprios, mesmo que só o Fisco/Contábil tenha regras cadastradas até agora.
- **8 models** (migrações `0024`–`0028`, `0033`–`0035`): `IndicadorDepartamento` (cadastro de departamentos — nome/ativo — usado pra escopar critérios, percentuais e metas de Departamento; ver "Departamento organizacional" abaixo), `IndicadorDepartamentoGerente` (relação gerente→departamento, mantida manualmente pela aplicação), `IndicadorPercentualTipo` (percentuais individual/grupo/departamento por tipo de colaborador **e por departamento**, histórico via `vigente_desde` — nunca editado in-place), `IndicadorCriterio` (cadastro genérico de critério: **departamento**/nome/grupo/peso/período/papel/`calculo_automatico`/`limiar_percentual`), `IndicadorApuracao` (uma apuração mensal — `competencia`, `status` `revisao`/`concluida`, as 2 planilhas anexadas, `avisos` de processamento), `IndicadorApuracaoColaborador` (um colaborador dentro de uma apuração, com `pct_individual`/`pct_grupo`/`pct_departamento` e respectivos flags `*_ajustado_manualmente`, mais `departamento` — FK pra `IndicadorDepartamento`, resolvida na criação via o gerente do colaborador, ver "Departamento organizacional" abaixo), `IndicadorApuracaoEmpresa` (uma empresa/honorário do colaborador naquele mês) e `IndicadorApuracaoResposta` (SIM/NÃO/NÃO FAZ/NÃO SE APLICA de um colaborador para um critério).
- **Tipo do colaborador é derivado por empresa, não é cadastro**: `TIPO_COLABORADOR_INDICADOR_CHOICES` (Contábil+Fiscal/Contador SC/Contador CC/Fiscal/Conciliador) — regra em `indicadores/tipos.py`, validada contra um recibo-modelo real (~99,99% de precisão no teste com 43 colaboradores).
- **3 critérios são calculados automaticamente** a partir da planilha "Serviços Tareffa" (`indicadores/entregas.py`/`pipeline.py`) — entrega de balancetes/liberações fiscais/conciliações no prazo, comparadas contra `IndicadorCriterio.limiar_percentual` pra decidir SIM/NÃO. Todo o resto é sempre marcação manual do RH (SIM/NÃO/NÃO FAZ/NÃO SE APLICA por critério, individual ou em lote). Um critério automático sem nenhum registro do serviço vira **NÃO SE APLICA**, não NÃO FAZ — permite deixar `papel_aplicavel` em branco nesses 3 critérios (um mesmo critério, ex. "balancete", se aplica a 3 tipos ao mesmo tempo, e `papel_aplicavel` só aceita um valor); quem não presta aquele serviço fica de fora do cálculo por conta própria (NÃO SE APLICA é excluído do denominador em `calculo.py`).
- **Fórmula**: `honorario_ajustado = honorario_empresa × pct_individual_do_colaborador`; `valor_individual = honorario_ajustado × percentual_individual(tipo)`; `valor_grupo`/`valor_departamento = valor_individual × percentual_grupo/departamento(tipo) × pct_grupo/departamento_do_colaborador`. `pct_individual` **não é só a média dos critérios Individual** — é a composição ponderada dos 3 níveis (Individual/Grupo/Departamento), cada um pesando conforme o peso médio dos seus próprios critérios aplicáveis na competência (`calculo._combina_niveis`/`_peso_medio_nivel`); só `pct_grupo`/`pct_departamento` continuam sendo a média simples dos próprios critérios, sem composição.
- **"Cada gerente representa um grupo", cada departamento representa um departamento** (não é redundante, ver abaixo): `pct_grupo` é conceitualmente compartilhado por todos os colaboradores com o mesmo `gerente` dentro da apuração, e `pct_departamento` é compartilhado por todos os colaboradores do mesmo `IndicadorDepartamento` (ver "Departamento organizacional" abaixo — não mais um valor único pra toda a apuração) — por isso não são ajustados colaborador a colaborador (`IndicadorApuracaoColaboradorViewSet` só cobre `pct_individual`); `IndicadorApuracaoViewSet.ajustar_grupo`/`recalcular_grupo`/`ajustar_departamento`/`recalcular_departamento` aplicam a mudança de uma vez a todo o grupo/departamento, mantendo os colaboradores em sincronia (`ajustar_departamento`/`recalcular_departamento` recebem `departamento` — o id do `IndicadorDepartamento` — no corpo, filtrando com um `.filter(departamento_id=...)` direto). A tela (`indicador-desempenho.js`) reflete isso com uma tabela de "Metas de Grupo e Departamento" no topo (uma linha de Departamento por `IndicadorDepartamento` + uma linha de Grupo por gerente dentro dele) separada da lista de colaboradores abaixo (que serve só pra revisão individual — percentual Individual, respostas de critério, recibo); botões de filtro por departamento (`#ind-filtro-departamento`, ver "Departamento organizacional" abaixo) restringem a tabela de Metas e a lista de colaboradores a um departamento de cada vez, sem afetar o cálculo de nenhuma meta. Colaborador cujo gerente não está mapeado a nenhum departamento cai num grupo "Sem departamento definido" (sem `<select>` de meta — não há `IndicadorDepartamento` pra aplicar). **A meta de Grupo/Departamento é sempre Sim/Não (100%/0%)**, nunca um percentual livre — decisão explícita do usuário ("será pago ou não") — por isso a coluna "Meta (%)" dessa tabela é um `<select class="ind-meta-select">` com só essas duas opções (`ehSim = valor >= 50` decide qual aparece selecionada ao carregar), não um campo de texto livre; o valor enviado a `ajustar-grupo`/`ajustar-departamento` é sempre `"100"` ou `"0"`. O percentual Individual de cada colaborador continua livre (é uma composição ponderada dos 3 níveis, pode legitimamente ser fracionário — ver acima).
- **Departamento organizacional** (`IndicadorDepartamento`/`IndicadorDepartamentoGerente`/`portal_api.indicadores.departamentos`) — substituiu, numa rodada posterior, o mecanismo de "setor" (coluna bruta "departamento" da planilha Tareffa + fusão automática Contabilidade/Fiscal→Fisco-Contábil + `IndicadorSetorApelido`, cadastro-exceção por colaborador). Agora **critérios e percentuais também são configurados por departamento** (não só as metas de Grupo/Departamento) — decisão explícita do usuário: a regra do Fisco/Contábil pode ser diferente da regra do Condomínio, por exemplo. `IndicadorDepartamento` (nome/ativo) é um cadastro simples, mantido pela própria aplicação (Configurações → Departamentos); a relação com gerentes (`IndicadorDepartamentoGerente`, `nome_gerente` único — um gerente pertence a só um departamento, mas um departamento pode ter vários gerentes, ex.: Fisco/Contábil tem "João Candido Rodrigues" **e** "Lhais Vergilio Delavy") também é mantida manualmente por ora — alimentar isso automaticamente a partir da planilha fica pra uma rodada futura (decisão explícita do usuário). Pra não obrigar o RH a redigitar nomes (arriscando um typo que faria uma apuração futura não casar com o departamento certo), o popup "Gerenciar Gerentes" (`indicador-desempenho.js`) mostra uma lista de **sugestões clicáveis** — `carregarGerentesSugeridos()` busca a apuração mais recente (`GET /api/indicadores-apuracoes/`, já ordenada por `-competencia`/`-criado_em`) e lista os nomes distintos de `colaborador.gerente` que ainda não estão em nenhum `IndicadorDepartamentoGerente`; clicar numa sugestão já cria a relação pra aquele departamento. É só um atalho de UI (não muda a origem do dado) — o campo de texto livre continua disponível pra gerentes que não apareceram na última apuração.
Resolução do departamento de um colaborador: `IndicadorApuracaoViewSet.create()` monta `mapa_gerentes` (`departamentos.carrega_mapa_gerentes()`, `{nome_gerente: departamento_id}`) uma vez e passa pro `pipeline.processa_apuracao()`, que resolve `departamento_id = mapa_gerentes.get(colaborador.gerente)` pra cada colaborador **antes** de decidir quais critérios automáticos calcular pra ele (críticos automáticos também são agrupados por `departamento_id` — `criterios_automaticos_por_departamento`, já que departamentos diferentes podem ter critérios/limiares diferentes). O resultado (`IndicadorApuracaoColaborador.departamento`, FK nullable) é um **retrato daquele momento** — mesmo espírito de `gerente`/`setor` antes dele: se a relação gerente→departamento mudar depois, apurações já criadas não mudam sozinhas. Colaborador cujo gerente não está mapeado a nenhum departamento fica com `departamento=None` e vira um aviso no processamento ("Gerente X não está associado a nenhum departamento..."), além de não ganhar nenhuma `IndicadorApuracaoResposta` (sem departamento, não há de onde vir nenhum critério). `IndicadorApuracaoColaboradorSerializer` expõe `departamento` (id) + `departamento_nome` (com fallback `None`, mesmo padrão de `criado_por_nome`).
**Migração em 3 passos** (mesmo padrão de qualquer FK obrigatória adicionada a uma tabela já populada): `0033` cria os 2 models novos + adiciona `departamento` nullable em `IndicadorCriterio`/`IndicadorPercentualTipo`/`IndicadorApuracaoColaborador` (e remove `setor`/`IndicadorSetorApelido`); `0034` (`RunPython`) cria o departamento "Fisco/Contábil" e aponta todo `IndicadorCriterio`/`IndicadorPercentualTipo` já existente pra ele (é literalmente o que a regra única representava até então); `0035` torna `departamento` obrigatório em `IndicadorCriterio`/`IndicadorPercentualTipo` (não em `IndicadorApuracaoColaborador`, que continua nullable). **Apurações criadas antes desta migração** (e qualquer apuração nova, até o admin mapear os gerentes relevantes em Configurações → Departamentos) ficam com `departamento` em branco em todos os colaboradores — precisam de um backfill pontual ou de serem reprocessadas depois que a relação gerente→departamento existir.
**Limitação conhecida, validada com dados reais**: como a resolução é por `gerente` (não por colaborador), dois subordinados diretos do mesmo gerente sempre caem no mesmo departamento — isso quebra o caso de uma gerente que supervisiona pessoas de **departamentos diferentes**. Ex. real: "Elizangela de Paula Kuhn" supervisiona diretamente os líderes de Fisco/Contábil (João Candido Rodrigues, Lhais Vergilio Delavy, Paloma Ramão, Elizangela dos Santos — departamento "Gerentes") **e** Luciane Gonzaga (que deveria cair em "Rocket", já que ela chefia esse outro departamento) — como todos compartilham o mesmo `gerente`, mapear "Elizangela de Paula Kuhn" → "Gerentes" também classifica Luciane Gonzaga como "Gerentes", não "Rocket". Não existe mais um mecanismo de exceção por colaborador individual (o antigo `IndicadorSetorApelido` cobria exatamente esse tipo de caso) — se isso for um problema real, precisa ser resolvido numa rodada futura (ex.: reintroduzindo uma exceção por nome de colaborador, por cima da relação gerente→departamento).
- **Detalhamento da composição no card do colaborador** (`portal_api.indicadores.calculo.composicao_individual`, exposto como o campo `composicao_individual` de `IndicadorApuracaoColaboradorSerializer`): reconstrói, só pra exibição, o percentual bruto de Individual (antes da composição) e o peso médio de cada um dos 3 níveis (`_peso_medio_nivel`) — dados que `recalcula_colaborador` calcula mas não persiste, por não precisar deles depois de gravar `pct_individual`. No cabeçalho do card (`indicador-desempenho.js`), essa linha ("Individual: X% (peso Y%) · Grupo: X% (peso Y%) · Departamento: X% (peso Y%)") fica ao lado do nome/gerente, numa coluna própria do grid centralizada — não embaixo — e cada um dos 3 níveis fica verde/vermelho conforme bateu 100% ou não; o "Total Indicador" (renomeado de "Individual", que é `pct_individual`, com o lápis de ajuste manual sempre ao lado do valor numa linha que não quebra) fica neutro, sem cor, pra não repetir a mesma informação 4 vezes. `composicao_individual()` usa `colaborador.respostas.all()` (não `.select_related("criterio")`) de propósito, pra reaproveitar o `prefetch_related("colaboradores__respostas__criterio")` que `IndicadorApuracaoViewSet.get_queryset()` aplica só na action `retrieve` — evita 1 query extra por colaborador ao abrir a tela de revisão.
- **Tabela "Metas de Grupo e Departamento" só tem uma forma de responder Sim/Não por critério** — a coluna "Meta (%)" (ajusta `pct_grupo`/`pct_departamento` direto). Existia um segundo `<select>` Sim/Não ao lado do texto de cada critério (bulk, via `aplicar-em-lote`), removido por ser redundante com o da direita; a lista de critérios ali agora é só informativa (nome + peso). Responder um critério específico continua possível por colaborador, dentro da lista de colaboradores abaixo (`renderRespostasGrupoHtml`).
- **"Corrigir Responsável"** (`#ind-corrigir-responsavel-btn`, popup próprio): busca uma empresa (por nome ou código, entre **todas** as empresas da apuração, não só as com problema de honorário — `empresasAgrupadasPorCodigo(() => true)`) e mostra, pra cada responsável dela (uma linha por `IndicadorApuracaoEmpresa`, ex.: "Valéria Bonete — Fiscal"), um `<select>` com os demais colaboradores da apuração pra reatribuir aquele papel. Reatribuir chama `POST /api/indicadores-apuracoes-empresas/{id}/trocar-responsavel/` (`IndicadorApuracaoEmpresaViewSet.trocar_responsavel`, serializer `IndicadorApuracaoEmpresaTrocarResponsavelSerializer` com `{colaborador_id}`), que só troca a FK `colaborador` da linha (`codigo_empresa`/`tipo`/honorário continuam os mesmos) e recalcula **os dois** colaboradores envolvidos (o que perdeu a empresa e o que ganhou) — validado no backend contra: colaborador de outra apuração, colaborador igual ao atual, e colaborador que já é responsável por essa mesma empresa/tipo (evitaria duas linhas duplicadas pra ele). O `<select>` exclui o colaborador atual das opções e nasce com um placeholder desabilitado ("Selecionar novo responsável...") pra nunca reatribuir sem escolha explícita.
- **Checklist de revisão do RH** (`IndicadorApuracaoColaborador.validado`, migração `0031`): um checkbox no início de cada card (`.ind-colaborador-card__validado`, primeira coluna do grid do cabeçalho), sem relação com nenhum cálculo — só ajuda o RH a controlar quem já conferiu numa apuração com muitos colaboradores. Marcado, a borda do card inteiro fica verde (`.ind-colaborador-card.is-validado`, mesma largura de sempre, só muda a cor, pra não deslocar layout). `POST /api/indicadores-apuracoes-colaboradores/{id}/marcar-validado/` (`marcar_validado`, serializer `IndicadorApuracaoColaboradorValidadoSerializer` com `{validado}`) só grava o campo, sem chamar `recalcula_colaborador`. Diferente dos outros ajustes desta tela, o frontend **não** recarrega a apuração inteira depois de marcar/desmarcar (`renderRevisao()`) — atualiza só o card clicado localmente, pra não fechar outros cards já expandidos nem perder a posição de rolagem no meio de uma conferência longa; erro de rede reverte o checkbox e o estado em memória (mesmo padrão de outros toggles imediatos do app, ex. inativar usuário). O `<label>` inteiro (não só o `<input>`) precisa ficar de fora do gate de clique que expande/recolhe o card no cabeçalho, senão um clique na área do label (fora do glifo do checkbox) expande/recolhe o card ao mesmo tempo que marca/desmarca o validado — resultado de como labels HTML disparam dois eventos de clique encadeados.
- **Forçar SIM num critério automático não vira 100% na média** — a média ponderada usa o percentual real medido (`_fracao_atingida` em `calculo.py`), mesmo que o RH marque SIM por cima; só critério manual (sem `percentual_calculado`) é binário SIM=100%/resto=0%. Pra dar crédito cheio apesar do percentual medido baixo, o RH ajusta o percentual agregado direto (nível 2 acima), não o critério.
- **`create()` é atômico**: `IndicadorApuracaoViewSet.create()` roda o pipeline inteiro (parse das 2 planilhas + persistência de colaboradores/empresas/respostas) dentro de `transaction.atomic()` — uma falha no meio (planilha fora do leiaute, overflow decimal) desfaz tudo no banco e apaga os 2 arquivos recém-gravados em `MEDIA_ROOT` (upload não é transacional), devolvendo 400 genérico.
- **`POST /api/indicadores-apuracoes/{id}/gerar/`** monta um **ZIP** com um PDF de recibo por colaborador (`indicadores/recibo.py`, `reportlab`) a partir do que já está salvo — não reprocessa as planilhas, reflete qualquer ajuste manual feito na revisão. Recibo é documento interno (só quem tem a permissão do RH acessa/baixa) — sem visão própria do colaborador no Portal nesta v1. Botão "Gerar Recibos" (`indicador-desempenho.js`) abre um modal antes de chamar o endpoint — mesmo componente de busca por nome + filtro por departamento + checklist (com "marcar todos os resultados da busca") do "Ajuste Indicador em Lote", só que já nasce com todo mundo marcado (reproduz o comportamento antigo de "gerar pra todos" sem precisar marcar um por um); desmarcar alguns permite gerar recibo avulso de um colaborador só, de alguns específicos, ou de um departamento inteiro. O endpoint recebe `colaborador_ids` (lista, opcional) e só marca a apuração como `concluida` quando o conjunto pedido bate com **todos** os colaboradores da apuração (sem `colaborador_ids`, ou uma seleção que cobre o total) — gerar um recibo avulso pra conferência não fecha a apuração inteira como se o mês estivesse todo revisado.
- **Layout do PDF do recibo** (`indicadores/recibo.py`): o banner "PERCENTUAL DO INDICADOR INDIVIDUAL" sempre mostra o percentual **efetivo/medido** (`calculo.composicao_individual()["total_calculado"]` — a composição dos 3 níveis recalculada na hora, ignorando qualquer ajuste manual), não `colaborador.pct_individual` puro — decisão explícita do usuário: se o RH/Diretoria sobrescreveu o Individual pra 100%, o banner precisa continuar mostrando o que o colaborador de fato atingiu (ex.: 74,29%), não o valor pago. Quando `pct_individual_ajustado_manualmente=True`, uma linha de detalhe abaixo do banner mostra "Percentual Individual Ajustado Pela Direção: **100,00%**." (rótulo renomeado de "ajustado manualmente pelo RH", com o valor ajustado ao lado — antes só dizia que tinha sido ajustado, sem mostrar pra quanto) — os dois números lado a lado deixam claro o que foi medido e o que foi pago. Tabela "Empresas": toda célula (antes só "Empresa" era `Paragraph`, o resto strings soltas) virou `Paragraph` com estilo de alinhamento próprio (`celula_centro`/`celula_direita`/`celula_negrito`/`celula_direita_negrito`, `_estilos()`) — string solta não quebra linha dentro da coluna, e com `ALIGN` à direita/centro um valor mais largo que a coluna (ex.: "Contador (com conciliador)" em Tipo, ou os totais em negrito, mais largos que a mesma string em peso normal) vazava visualmente por cima da célula vizinha em vez de quebrar linha — bug real visto com dados reais (coluna Tipo cobria "Hon. Ajustado"). Coluna "Tipo" ganhou um dicionário de labels curtos só pro PDF (`TIPO_LABEL_CURTO`: "Contador SC"/"Contador CC" em vez de "Contador (sem/com conciliador)" — mesma abreviação já usada informalmente neste documento) porque o label completo não cabia nem quebrando linha numa coluna estreita; a linha de total virou "Total do Indicador" (era "Total Resultado"). Larguras de coluna e padding lateral (`LEFTPADDING`/`RIGHTPADDING`, reduzidos de 6pt padrão do reportlab pra 3pt) ajustados pra caber os maiores valores reais vistos na apuração (ex.: R$ 28.023,16) numa linha só. `_moeda()` usa `&nbsp;` (não espaço comum) entre "R$" e o número — com espaço comum, quando o valor não cabia numa linha só, o reportlab quebrava exatamente ali, deixando "R$" sozinho numa linha acima do número; com espaço não separável, o "R$" fica sempre grudado à esquerda do número (mesmo que precise de mais espaço na coluna pra caber tudo numa linha, resolvido junto pelas larguras/padding acima). Rótulo da linha de detalhe é "Percentual individual ajustado pela direção" (minúsculo, só a primeira letra maiúscula — não "Percentual Individual Ajustado Pela Direção").
- **`aplicar_em_lote`** (`IndicadorApuracaoRespostaViewSet`, `POST /api/indicadores-apuracoes-respostas/aplicar-em-lote/`) aplica o mesmo valor a várias respostas de critério de uma vez — a "múltipla seleção" pedida pelo usuário na tela de revisão.
- **"Empresas sem Honorário"** (`#ind-empresas-sem-honorario-btn`, cor de atenção — `--danger`, mesma linguagem visual do input/selo de honorário não encontrado, **só enquanto houver alguma empresa pendente** — sem nada pra resolver, o botão perde a classe `.ind-empresas-sem-honorario-btn` (volta a `.btn-outline` neutro) e o texto vira "Visualizar Empresas com Honorário Ajustado (N)", apontando direto pra revisão do que já foi ajustado — substituiu o antigo checkbox "Só com honorário não encontrado" que filtrava a lista de colaboradores): abre um modal que agrupa por `codigo_empresa` todas as `IndicadorApuracaoEmpresa` com `honorario_nao_encontrado=True` da apuração — a mesma empresa pode aparecer sob mais de um colaborador (um responsável pelo balancete, outro pela liberação fiscal, outro pela conciliação financeira), mas o honorário é da empresa, não da pessoa. Preencher um valor ali chama `POST /api/indicadores-apuracoes/{id}/ajustar-honorario-empresa/` (`IndicadorApuracaoViewSet.ajustar_honorario_empresa`, serializer `IndicadorApuracaoAjusteHonorarioEmpresaSerializer` com `{codigo_empresa, honorario}`), que atualiza **todas** as linhas daquele código nesta apuração de uma vez (recalculando cada colaborador afetado) — diferente de `PATCH /api/indicadores-apuracoes-empresas/{id}/` (ainda existe, ajusta só uma linha por id, usado direto na tabela "Empresas" de dentro do card do colaborador). Os dois caminhos (linha única e em lote) marcam `honorario_ajustado_manualmente=True` na(s) linha(s) afetada(s) — fica permanente (sem UI de reverter, diferente de `pct_individual_ajustado_manualmente`/etc., já que não existe um "automático" pra voltar quando o código nunca casou com a planilha) e vira uma nota "honorário ajustado manualmente" (cor `--accent`) ao lado do valor, na tabela "Empresas" de dentro do card do colaborador — visível só depois que `honorario_nao_encontrado` já foi resolvido (os dois nunca aparecem juntos). Essa tabela também passou a listar por `codigo_empresa` (`IndicadorApuracaoEmpresa.Meta.ordering`, migração `0029`), não mais por nome. Como `codigo_empresa` é `CharField`, ordenar só por ele é ordem alfabética, não numérica — "80"/"503" apareciam depois de "2134" (o caractere `'8'`/`'5'` é "maior" que `'1'`/`'2'`, mesmo o número sendo menor). Corrigido (migração `0030`) ordenando primeiro pelo **tamanho** da string (`Length("codigo_empresa")`) e só depois pelo valor — reproduz a ordem numérica certa pra códigos sem zero à esquerda (string mais curta = número menor, sempre) sem converter pra inteiro, o que quebraria com erro de banco se algum código um dia não fosse só dígitos.
- **"Empresas ajustadas manualmente"** é uma **segunda seção dentro do mesmo popup** "Empresas sem Honorário" — não um segundo botão/modal (revertido de propósito: nasceu como um botão separado, "Verificar Empresas Ajustadas Manualmente", e o usuário pediu pra unificar num popup só, "facilitando a usabilidade da ferramenta"). Fica **escondida por padrão**, atrás de um botão de largura cheia no final da lista principal (`#ind-empresas-ajustadas-toggle-btn`, `.ind-esh-toggle-btn`, com contador — "Visualizar"/"Ocultar Empresas Ajustadas Manualmente (N)") — pedido explícito do usuário logo depois de testar a versão anterior (as duas seções sempre visíveis de uma vez): a lista secundária só deve aparecer sob demanda, no final do modal. Lista, também agrupada por `codigo_empresa`, as empresas com `honorario_ajustado_manualmente=True` — permite **corrigir** um valor já ajustado (campo já vem preenchido com o honorário atual, ao contrário da lista principal, que começa em branco). Reaproveita o mesmo endpoint `ajustar-honorario-empresa` — o filtro do backend cobre `Q(honorario_nao_encontrado=True) | Q(honorario_ajustado_manualmente=True)`, nunca uma empresa cujo honorário só veio certo da planilha e nunca foi mexido. As duas listas compartilham as funções de agrupamento/renderização/ordenação (`empresasAgrupadasPorCodigo`, `renderEmpresaGrupoItemHtml`) em `indicador-desempenho.js`, parametrizadas só pelo filtro; `renderEmpresasHonorario()` sempre re-renderiza a lista principal e só re-renderiza a de "ajustadas" **se a seção já estiver aberta** (ao abrir o popup, essa seção sempre volta a fechar) — necessário porque corrigir uma empresa "sem honorário" faz ela migrar pra lista de "ajustadas" na hora, e essa migração só precisa refletir de imediato se o usuário já estiver olhando pra ela. As duas ficam dentro de um único wrapper que rola (`.ind-esh-scroll`), com título e "Fechar" sempre visíveis fora dele (mesmo `max-height:85vh` do popup). Em cada item, o código aparece **antes** do nome da empresa no cabeçalho (`.ind-esh-codigo` seguido de `.ind-esh-nome`), mesma ordem da tabela "Empresas" do colaborador.
- **"Ajuste Indicador em Lote"** (`#ind-lote-global-btn`, `indicador-desempenho.js`): modal separado do anterior — ajusta `pct_individual` (não critérios) de vários colaboradores **selecionados por nome** de uma vez, pra dois casos binários só: "Ajustar" (`#ind-lote-global-ajustar-btn`, aplica `pct_individual=100` a todos, via `PATCH /api/indicadores-apuracoes-colaboradores/{id}/`) ou "Reverter" (chama a action `recalcular` de cada um, voltando ao cálculo automático) — sem campo de percentual livre. Os dois botões são `btn-solid` (mesma cor) — só "Cancelar" fica `btn-outline`, já que as duas ações são igualmente "reais", não uma primária e uma secundária. Não existe endpoint de lote dedicado pra isso; o frontend dispara um PATCH/POST por colaborador em paralelo (`Promise.all`).
- **Percentuais/critérios são cadastro editável pela tela**, não hardcoded — decisão explícita do usuário pra não fixar no código números incertos vindos da planilha antiga já quebrada. Primeiro histórico populado via `python manage.py seed_indicador_desempenho` (idempotente), com os valores exatos da planilha antiga (`vigente_desde` fixado em 01/01/2024 por falta de data documentada — ajustar se o usuário informar a data real).
- **Bugs de robustez corrigidos ao testar com 43 colaboradores reais**: `openpyxl.load_workbook(..., read_only=True)` precisa de `.close()` explícito (`indicadores/leiaute.py`), senão o Windows mantém o upload memory-mapped e bloqueia excluir a apuração depois; campos percentuais precisaram de `max_digits=7` (não 6) — qualquer `DecimalField` que representa um percentual "de 0 a 100" precisa de `max_digits >= decimal_places + 3` pra caber o "100" exato sem `DataError: numeric field overflow`.
## Importação de Plano de Saúde (Utilitários)
Primeira e única aplicação dentro de "Utilitários" (os placeholders "Conversor de Arquivos"/"Calculadora Fiscal" foram removidos do menu — decisão explícita do usuário, não recriar sem confirmar de novo) — importa o relatório de faturamento de uma operadora de plano de saúde/odontológico (Amil, Unimed, ...) e gera o arquivo de lançamento no leiaute fixo do Questor, mais um relatório de auditoria do que não pôde ser lançado automaticamente. Ao contrário dos módulos com tela administrável (Links & Ferramentas, Acessos Gerais, Ramais), essa ferramenta usa permissão de **toggle único** (`{"key": "importacao-plano-saude", "label": "..."}`, entrada flat em `catalogo.MODULE_APPS["utilitarios"]`, sem par visualizar/editar) — quem tem acesso pode fazer todo o fluxo (criar, revisar/editar, gerar), sem conceito de "dono" da importação (mesmo espírito compartilhado de `LinkFerramenta`/`AcessoGeral`). Por ser um app flat, não precisou de nenhum override em `seed_portal.py` (esse cuidado só existe pra pares visualizar/editar).
**A lógica de negócio em si não nasceu neste projeto** — veio de um pipeline Python já testado e documentado em `projects/importacao-planos-saude.skill` (arquivo `.skill`, é um zip — `SKILL.md` + `scripts/`), com um protótipo funcional em `projects/project/` (CLI `main.py`, nunca tocado pelo Portal, fica só como referência/histórico). Esse pipeline foi portado quase 1:1 para dentro do Django em **`portal_api/planos_saude/`** (pacote Python puro, sem depender do ORM):
```
portal_api/planos_saude/
├── modelos.py Lancamento, Individuo, LinhaSistema, ItemAuditoria (dataclasses)
├── matcher.py casa_individuos_com_planilha() — casamento por CPF ou por nome
├── leiaute_sistema.py CABECALHO, le_planilha_padrao(), formata_valor_br()
├── pipeline.py OPERADORAS (registro), processa_importacao() — orquestração, chamada pela view
└── operadoras/
├── base.py OperadoraParser (interface)
├── amil/odonto_mensalidade.py Amil Odonto (PDF via pdfplumber, só mensalidade, casamento por CPF)
├── unimed/saude.py Unimed (CSV, mensalidade+coparticipação, casamento por nome)
├── itamed/saude.py Itamed Saúde (PDF via pdfplumber, mensalidade+coparticipação, casamento por nome)
├── dental_uni/odonto_mensalidade.py Dental Uni Odonto (PDF via pdfplumber, só mensalidade, casamento por nome)
└── unimed_oeste_pr/saude.py Unimed Oeste do Paraná (PDF via pdfplumber, mensalidade+coparticipação por texto da descrição, casamento por nome)
```
Pra adicionar uma operadora nova: criar `operadoras/<nome>/<arquivo>.py` implementando `OperadoraParser.extrai()` (devolve `(List[Individuo], List[ItemAuditoria])`) e registrar em `pipeline.OPERADORAS`. **Antes de escrever o parser, ler `projects/importacao-planos-saude.skill`** — documenta decisões de negócio já validadas com o cliente (ex.: nome divergente nunca é resolvido por aproximação, valor final negativo vai pra auditoria, um mesmo beneficiário pode aparecer em várias linhas/rubricas e precisa ser somado) que não devem ser reinterpretadas sem confirmar de novo.
**Diferença deliberada em relação ao pipeline original**: lá, o valor do mês sempre gravava na coluna `VALOR` (desconto do empregado), nunca em `VALOREMPRESA` — regra fixa. Aqui, o usuário escolhe na tela de nova importação, **por tipo de lançamento (mensalidade/coparticipação) e por tipo de beneficiário (titular/dependente)** — quatro combinações independentes, ex.: mensalidade do titular custeada pela empresa e mensalidade do dependente descontada do empregado —, uma de três regras de custeio: "Custeado pela empresa" (`{"modo": "empresa"}`), "Descontado do empregado" (`{"modo": "empregado"}`, o comportamento antigo — nomenclatura "empregado", não "funcionário", pra não confundir com `NOMEFUNC`/`CPFFUNC` do leiaute do Questor, que é outra coisa) ou "Regra específica" (`{"modo": "especifica", "limite_valor": float|None, "percentual": float|None}`). Na regra específica, `limite_valor` é um teto de quanto a empresa cobre (o excedente vira desconto do empregado) e `percentual` é a fração do valor do mês custeada pela empresa (o resto vira desconto) — o usuário pode preencher só um dos dois ou os dois juntos; quando os dois vêm preenchidos, prevalece o que resultar no **menor** valor custeado pela empresa (mais restritivo), decisão explícita do usuário. Essa divisão é calculada por `matcher._calcula_valores(valor_total, regra)` (chamada por `_aplica_regra_custeio`, que grava `valor_empresa`/`valor` **os dois juntos** a partir do mesmo `valor_total`) — note que `valor_empresa` é arredondado primeiro e `valor` é derivado como o complemento exato (`valor_total - valor_empresa`, também arredondado), nunca os dois arredondados de forma independente, senão a soma dos dois podia ficar 1 centavo a mais/menos que o valor original (ex.: 50% de 51,69 tem que fechar em 25,84 + 25,85 = 51,69, não 25,85 + 25,85). Qual das duas regras (titular ou dependente) usar em cada `Individuo`/`LinhaSistema` é resolvido por `matcher._regra_para_pessoa(regra_por_pessoa, tipo_pessoa)` — `tipo_pessoa` 'T' cai em "titular", 'D'/'A' caem em "dependente" (mesmo critério de "D e A tratados igual" já usado no resto do leiaute) — chamada nos dois pontos de aplicação de `_casa_por_cpf`/`_casa_por_nome` antes de `_aplica_regra_custeio`.
### Modelos (`portal_api/models.py`)
- `ImportacaoPlanoSaude`: uma execução da ferramenta — `operadora`/`nome_operadora`, `tipos_lancamento` (JSONField, lista), `custeio_por_tipo` (JSONField, `{"mensalidade": {"titular": {"modo": "empresa"|"empregado"|"especifica", "limite_valor": float|None, "percentual": float|None}, "dependente": {...}}, "coparticipacao": {...}}` — ver regra de custeio acima), os dois arquivos anexados (`planilha_padrao`/`arquivo_operadora`, `FileField` com o mesmo padrão de validator de tamanho de `LinkFerramenta.icone`, só que 15MB em vez de 2MB — são documentos reais, não ícones), `status` (`revisao`/`concluida`), `criado_por`, `criado_em`/`concluida_em`. **Com histórico**: decisão explícita do usuário — cada importação fica salva (quem fez, quando, arquivos), não é um fluxo descartável.
- `ImportacaoPlanoSaudeLinha`: uma linha da planilha padrão já casada com o valor do mês (espelha `LinhaSistema` campo a campo) — **todos os campos são editáveis** na tela de revisão antes de gerar o CSV (decisão explícita do usuário, não só os valores). `valor`/`valor_empresa` ficam como `CharField` no mesmo formato string do pipeline (`"51,69"`/`"0"`), não `DecimalField`, pra manter fidelidade 1:1 com o CSV final sem risco de arredondamento.
- `ImportacaoPlanoSaudeAuditoria`: espelha `ItemAuditoria` — os campos extraídos do arquivo da operadora (`motivo`/`nome`/`valor`/`detalhe`...) são read-only na tela; `resolvida`/`linha_vinculada` são a exceção, graváveis via a resolução manual (ver "Resolução manual de auditoria por nome" abaixo). `MOTIVOS_RESOLVIVEIS = ("NOME_DIVERGENTE", "NAO_CADASTRADO")` (atributo de classe) é a lista dos dois motivos "de leitura/grafia de nome" que aceitam esse fluxo — `VALOR_NEGATIVO`/`TIPO_INVALIDO` são outra categoria de problema (valor real negativo, tipo de despesa não mapeado) e não têm solução por "essa é a mesma pessoa".
- `RegraCusteioPlanoSaude`: regra de custeio salva pra reaplicar em importações futuras (ex.: "092 - Unimed") — ver "Regras de custeio salvas" abaixo. Lista compartilhada (sem FK pra `ImportacaoPlanoSaude`), mesmo espírito de `LinkFerramenta`/`AcessoGeral`.
### Fluxo e endpoints
`ImportacaoPlanoSaudeViewSet` (`/api/importacoes-plano-saude/`, `PermissaoApp("utilitarios", "importacao-plano-saude")` pra todos os métodos):
- `create()` (multipart, `ImportacaoPlanoSaudeCreateSerializer` valida a entrada) salva o model (isso já grava os 2 arquivos em `MEDIA_ROOT`) e roda `pipeline.processa_importacao()` **de forma síncrona** usando `instance.arquivo_operadora.path`/`instance.planilha_padrao.path` — sem fila/Celery, o arquivo típico processa em menos de um request. Se o processamento falhar (PDF num layout desconhecido etc.), apaga os arquivos recém-salvos + o registro órfão e devolve 400.
- `GET /operadoras/` (`@action` sem detail) devolve `pipeline.lista_operadoras()` — fonte única pro `<select>` do formulário, sem duplicar a lista em JS.
- `POST /{id}/gerar/` monta o(s) CSV(s) a partir das **linhas já salvas** (isto é, já com qualquer edição feita na revisão — não reprocessa os arquivos originais) usando `leiaute_sistema.CABECALHO`; 1 tipo de lançamento vira um `.csv` direto, 2 tipos (mensalidade + coparticipação) viram um `.zip` com um `.csv` por tipo (`zipfile` em memória). Pode ser chamada de novo pra regerar depois de mais edições — não bloqueia edição subsequente.
`ImportacaoPlanoSaudeLinhaViewSet` (`/api/importacoes-plano-saude-linhas/{id}/`, só GET/PATCH): edição de uma linha por vez, disparada por `blur`/`change` de cada `<input>` na tela de revisão — mesma permissão de toggle único, sem checagem de "dono".
`ImportacaoPlanoSaudeAuditoriaViewSet` (`/api/importacoes-plano-saude-auditoria/{id}/resolver/`, só `POST`) — ver seção própria abaixo.
### Resolução manual de auditoria por nome
Quando o casamento por nome falha (`NOME_DIVERGENTE`/`NAO_CADASTRADO` — ver `matcher.py`, "nunca resolvido por aproximação automática"), o colaborador pode confirmar manualmente que aquele item **é** uma pessoa específica já presente na planilha padrão, em vez de deixar o lançamento parado em auditoria pra sempre. Não é fuzzy matching nem aproximação automática — é sempre uma confirmação humana, explícita, item por item; a regra de "nome exato ou vai pra auditoria" do `matcher.py` continua intocada.
- **Endpoint**: `POST /api/importacoes-plano-saude-auditoria/{id}/resolver/` com `{"linha_id": <id>}`. Validações em `ImportacaoPlanoSaudeAuditoriaViewSet.resolver` (views.py): o item precisa ter um motivo em `MOTIVOS_RESOLVIVEIS` e ainda não estar `resolvida` (idempotente — não dá pra resolver de novo, nem trocar o vínculo depois); a linha escolhida precisa (a) ser da mesma importação e do mesmo `tipo_lancamento` do item; (b) ser do mesmo "lado" — titular pra item `tipo="T"`, dependente pra `tipo!="T"` (D/A) — comparando `linha.nome_dependente`/`cpf_dependente` vazios ou não; (c) **ainda estar em branco** (`valor == valor_empresa == "0"`), decisão explícita do usuário pra nunca sobrescrever sem querer um lançamento que já casou automaticamente com outra pessoa do arquivo da operadora.
- Ao vincular, o `valor` do item de auditoria é dividido em `valor_empresa`/`valor` pela mesma regra de custeio já salva em `ImportacaoPlanoSaude.custeio_por_tipo[tipo_lancamento]` para aquele tipo de pessoa (titular/dependente) — `matcher.valores_formatados_para_pessoa(valor_total, regra_por_pessoa, tipo_pessoa)` é o único ponto de entrada público do módulo pra isso, reaproveitando as mesmas `_regra_para_pessoa`/`_calcula_valores` do fluxo automático (não existe uma segunda fórmula "manual").
- O item **nunca é apagado nem some da lista**: fica marcado `resolvida=True` + `linha_vinculada` (FK), e a tela mostra um selo "Resolvido — <nome>" (verde, mesma linguagem visual de `.status-pill--ativo`) no lugar do botão "Vincular pessoa" — mantém o rastro de que aquele valor entrou por confirmação manual, não pelo casamento automático (mesma filosofia de histórico completo do resto do módulo). `get_resumo_por_tipo` (serializers.py) só conta itens **não resolvidos** em `total_auditoria`, pra não inflar o contador de pendências com algo que já foi lançado.
- **Frontend** (`importacao-plano-saude.js`): a coluna "Ação" da aba Auditoria (`panelHtmlAuditoria()`) mostra o botão "Vincular pessoa" só quando `PID_IPS_MOTIVOS_RESOLVIVEIS.includes(item.motivo)` e `!item.resolvida`. O modal `#ips-vincular-modal` lista candidatos **sem nenhuma chamada de API nova** — filtra em memória a partir de `importacaoAtual.linhas` (já carregado na revisão) por `tipo_lancamento` igual, "lado" (titular/dependente) igual e ainda em branco (`candidatosVincular()`), com uma caixa de busca por nome (`renderVincularLista()`, mesmo componente `.checklist-box`/`.checklist-search` de outras telas, aqui com `<input type="radio">` — seleção única, não múltipla). Confirmar chama `pidResolverAuditoriaPlanoSaude()` e refaz `pidFetchImportacaoPlanoSaude` pra recarregar `importacaoAtual` (mesmo padrão de "adicionar/remover linha" já usado na página) antes de re-renderizar as abas — a tabela do próprio tipo de lançamento também reflete o novo valor lançado, não só a aba Auditoria.
### Pré-validação de arquivo ao anexar (tela de Nova Importação)
Antes de existir isso, os dois arquivos (planilha padrão + arquivo da operadora) só eram validados juntos, no `create()`, e um erro de formato virava a mensagem genérica "O formato de um dos arquivos não está conforme o esperado" — sem dizer qual dos dois. Agora cada anexo é validado sozinho, no momento em que é selecionado, reaproveitando exatamente o mesmo parser que `create()` usaria — sem duplicar nenhuma regra de leiaute em JS (o parsing de PDF/CSV é Python-only, então isso teria que ser uma chamada ao servidor de qualquer forma).
- **Endpoint**: `POST /api/importacoes-plano-saude/validar-arquivo/` (multipart `{tipo: "planilha"|"operadora", arquivo, operadora?}`) — sempre `200 {"valido": bool, "mensagem": str}`, nunca um erro HTTP pra "arquivo errado" (esse é um resultado esperado da validação, não uma falha de requisição; só falta de `arquivo`/`tipo` inválido/`operadora` ausente quando `tipo="operadora"` vira 400 de verdade). `_valida_planilha_padrao()` roda `leiaute_sistema.le_planilha_padrao()`; `_valida_arquivo_operadora()` roda `OPERADORAS[operadora_key]["parser"]().extrai()` — os dois gravam o upload num arquivo temporário (`_salva_arquivo_temporario`, `tempfile.NamedTemporaryFile`) só porque essas funções esperam um caminho de arquivo, não um objeto de upload em memória, e apagam o temporário no `finally`; **nada é persistido**. Qualquer exceção do parser (coluna faltando, layout de PDF não reconhecido, CSV com delimitador errado — inclusive o caso real já visto de export com `\t` em vez de `;`) vira `valido=False` com uma mensagem específica pra aquele arquivo; 0 linhas/indivíduos extraídos (arquivo no formato certo mas vazio) também vira `valido=False`.
- **Frontend** (`importacao-plano-saude.js`): `criarValidadorArquivo()` é a fábrica reaproveitada pelos dois campos (`validadorPlanilha`/`validadorArquivo`) — no `change` do `<input type="file">`, chama `pidValidarArquivoPlanoSaude()` e mostra o resultado abaixo do campo (`.ips-file-field__status`, cores diferentes pra pendente/ok/erro). Cada campo ganhou um botão de remover (`.ips-file-field__remove`, ícone X — só aparece com um arquivo anexado) que limpa o `<input>` e o estado de validação, pro colaborador poder tentar outro arquivo sem precisar recarregar a página quando o anexado voltar como divergente. Trocar a operadora depois de já ter anexado o arquivo dela (`formOperadora` `change`) reexecuta a validação automaticamente (`revalidarSeAnexado()`) — o parser usado depende de qual operadora está selecionada, então um arquivo validado contra a operadora errada precisa ser checado de novo. O botão "Processar" bloqueia (`ehInvalido()`) se qualquer um dos dois arquivos já voltou `valido=False` — mas isso é só uma segunda barreira de UX; o `create()` no servidor continua sendo a validação real e definitiva.
Gerar o arquivo é um download binário (CSV ou ZIP), não JSON — por isso `pidGerarArquivoPlanoSaude()` não usa `pidApiRequest` (que sempre tenta `JSON.parse`); faz um `fetch` manual reaproveitando `pidEnsureCsrfCookie`/`pidGetCookie`/`pidErrorMessageFrom` de `api.js` (funções globais na página) e dispara o download via `URL.createObjectURL`.
### Regras de custeio salvas
Substituiu o antigo par de botões "Exportar regra"/"Importar regra" (baixava/lia um `.json` manualmente, sem nenhuma persistência) por um banco de regras de verdade no Postgres (`RegraCusteioPlanoSaude`) — pedido explícito do usuário pra poder nomear uma regra (ex.: "092 - Unimed"), escolhê-la numa lista em importações futuras, editá-la depois e anotar uma observação livre (ex.: "Empresa não desconta plano do empregado XX").
- **Campos**: `nome` (obrigatório), `operadora` (opcional — a `key` de `planos_saude.pipeline.OPERADORAS`, não o label; só usada pra pré-selecionar o `<select>` de operadora ao aplicar a regra, nunca bloqueia aplicar uma regra com uma operadora diferente da atual), `tipos_lancamento`/`custeio_por_tipo` (exatamente o mesmo formato dos campos homônimos de `ImportacaoPlanoSaude`, ver acima) e `observacoes` (texto livre).
- **Validação reaproveitada, não duplicada**: `RegraCusteioPlanoSaudeSerializer.validate()` e `ImportacaoPlanoSaudeCreateSerializer.validate()` chamam a mesma função módulo-level `_monta_regra_custeio()` (`serializers.py`) pra validar/parsear cada combinação tipo×pessoa — sem isso, a regra de negócio de custeio (parsing BR, faixa 0–100 do percentual, "ao menos um de limite/percentual") viveria duplicada em dois serializers e podia divergir com o tempo. A única diferença entre os dois pontos de entrada é o formato de payload: `ImportacaoPlanoSaudeCreateSerializer` recebe campos multipart achatados (`custeio_mensalidade_titular`, `limite_valor_mensalidade_titular`...), `RegraCusteioPlanoSaudeSerializer` recebe o `custeio_por_tipo` já aninhado como JSON puro.
- **`limite_valor`/`percentual` sempre em texto BR na entrada, float|None persistido**: igual ao resto do módulo, esses dois campos chegam como string BR (`"150,00"`) tanto no create de uma importação quanto no banco de regras — mas uma regra salva, uma vez lida de volta pelo `GET`, já vem com esses valores como `float` (formato final persistido). Pra `RegraCusteioPlanoSaudeSerializer` aceitar os dois formatos sem corromper o valor (`"150.0"` seria lido errado como 15000 por `parse_valor_br`, que só entende separador de milhar `.`/decimal `,`), `_valor_custeio_para_texto_br()` normaliza um float de volta pra texto BR (`formata_valor_br`) antes de repassar pro parser — isso é o que permite reenviar uma regra sem edição (ex.: só mudando o nome) sem precisar reformatar nada no frontend.
- **Frontend** (`importacao-plano-saude.js`, seção "Regra de custeio salva" — **primeiro** campo do formulário de Nova Importação, antes até de "Operadora": decisão explícita do usuário, já que aplicar uma regra já preenche a operadora junto, então escolher a regra é o primeiro passo natural do fluxo, não um apêndice no final): um combobox pesquisável (`#ips-regra-combo` — `<input>` `#ips-regra-search` + lista flutuante `#ips-regra-combo-list`, filtra por nome a cada tecla; era um `<select>` simples, trocado quando o banco de regras cresceu o bastante pra não caber numa lista sem busca) + "Aplicar" preenche o formulário inteiro (tipos de lançamento + custeio de cada combinação + operadora, se ainda existir na lista) a partir de uma regra salva — os campos continuam 100% editáveis depois, é só um preenchimento em massa (`aplicarCusteio()`/`aplicarRegraNoFormulario()`), mesmo espírito do antigo "Importar regra". `regraSelecionadaId` (JS) rastreia o que está de fato escolhido no combobox — digitar de novo no campo invalida a seleção anterior até o usuário clicar numa regra da lista, pra "Aplicar" nunca usar uma regra desatualizada em relação ao texto exibido. "Salvar regra atual..." (`#ips-regra-salvar-btn`) abre um modal (`#ips-regra-save-modal`) pra nomear/descrever a configuração atualmente preenchida (validada antes com a mesma `mensagemErroCusteio()` usada pelo botão "Processar", reaproveitada pelas duas ações) — **editar uma regra existente é literalmente aplicá-la, ajustar o que quiser no formulário, e salvar de novo**: o modal nasce em modo "atualizar a regra selecionada" sempre que a regra atualmente refletida no formulário (`regraAplicadaId`) ainda existir, com uma checkbox pra optar por "criar uma nova regra" em vez de sobrescrever. "Ver regras salvas" (`#ips-regras-modal`) lista todas as regras (nome, operadora, tipos, observações) com ações de Aplicar/Excluir — não duplica a grade de custeio num modal separado, de propósito, pra não manter dois lugares editáveis da mesma coisa.
## CSS — organização entre arquivos
| Arquivo | Contém |
|---|---|
| `tokens.css` | Variáveis (`:root`, tema claro em `:root[data-theme="light"]`). |
| `base.css` | Reset global, incluindo `[hidden] { display: none !important; }` — necessário porque vários componentes (`.no-access`, `.app-card`, `.notif-badge`) definem seu próprio `display`, o que sem o `!important` sobrescreveria o comportamento nativo de `hidden`. Também os `@keyframes` globais de animação (`pidFadeIn`/`pidFadeSlideUp`/`pidScaleIn`, ver "Animações" abaixo), já que é o único CSS carregado por **todas** as páginas sem exceção (inclusive `index.html`). |
| `layout.css` | Casca do shell: `.app-shell`, `.sidebar*`, `.nav-*`, `.fav-toggle`, `.topbar*`. A sidebar usa tokens **congelados**, independentes de tema (fundo sempre escuro em claro/escuro) — não trocar por variáveis que espelham `:root[data-theme="light"]`. Exceção deliberada: `--sidebar-text-primary`/`--sidebar-text-secondary`/`--sidebar-text-muted` (texto/ícone do menu) *são* sobrescritas em `:root[data-theme="light"]` (`tokens.css`) pra branco puro — pedido explícito do usuário pra melhorar a legibilidade; só o fundo/borda da sidebar continuam frozen. Também `.page-content` (largura do conteúdo de cada página, `max-width:1200px` centralizado por padrão) + o modificador `.page-content--wide` (`max-width:1600px`) — `portal.html` ("Principal") é a única página que usa só `.page-content` puro (grade de favoritos fica mais confortável de leitura mais estreita); as outras 7 páginas (`perfis-acesso.html`, `usuarios.html`, `links-ferramentas.html`, `acessos-gerais.html`, `ramais.html`, `calendario-individual.html`, `importacao-plano-saude.html`) usam `class="page-content page-content--wide"` no `<main>`, decisão explícita do usuário pra aproveitar melhor o espaço entre a sidebar e a borda da tela em telas de tabela/formulário. Uma página nova que seja mais "aplicação" (tabela, formulário, CRUD) do que "dashboard" deve nascer já com `page-content--wide`. |
| `components.css` | UI genérica reutilizável: `.btn-solid/.btn-outline/.btn-ghost/.btn-danger-outline`, **`.modal-overlay`/`.modal-card`** (moldura genérica de modal) **e também** `.modal-field`/`.modal-field-row`/`.modal-checkbox`/`.modal-error`/`.modal-actions` (campos internos do modal — moldura e campos vivem juntos aqui, apesar do nome sugerir só a moldura, incluindo `select`/`textarea` dentro de `.modal-field`, com seta customizada via `background-image` porque o nativo do browser destoa do tema escuro), `.app-card*`, `.no-access`, `.checklist-box`/`.checklist-item`/`.checklist-item__info`/`.checklist-item__nome`/`.checklist-item__departamento`/`.checklist-empty`/`.checklist-search`/`.checklist-select-all` (lista com checkbox, segunda linha de detalhe e busca — usada em `usuarios.html` e no modal "Gerenciar Usuário" de todo shell, ver seção "Liderança"). |
| `perfis-acesso.css` | `.pa-*` (tela de Perfis de Acesso), incluindo as seções (`.ua-section*`) e campos específicos (`.ua-inline-add`/`.ua-departamento-item`/`.ua-active-toggle`/`.ua-liderados-field`) do formulário de edição de `usuarios.html`. |
| `calendario.css` | Só `.calendar-*` (grade mensal, células de dia, nav do mês) — os campos do modal de compromisso usam as classes genéricas `.modal-field`/`.modal-checkbox`/`.modal-error`/`.modal-actions` de `components.css`. |
| `widgets.css` | `.widgets-*`, `.widget-card*`, `.widget-picker-*` — só usado em `portal.html`; também tem `#portal-title` (fonte "Bree Serif" do título "Portal De Paula" no topbar), que não é widget mas mora aqui por ser o único CSS próprio da página. |
| `login.css` | Só usado em `index.html`; `.login-card__title` ("Portal De Paula") usa a mesma fonte "Bree Serif" do `#portal-title` de `portal.html`. |
| `links-ferramentas.css` | `.lf-*` — só usado em `links-ferramentas.html`. |
| `acessos-gerais.css` | `.ag-*` — só usado em `acessos-gerais.html`. |
| `ramais.css` | `.ram-*` — só usado em `ramais.html`; a tabela em si reaproveita `.pa-table*`/`.pa-row-actions` de `perfis-acesso.css` (mesmo padrão que `usuarios.html` já usa sem CSS próprio). |
| `ramais-lookup.css` | `.ram-lookup-*` — modal de consulta rápida de ramais (ver "Ramais" abaixo), usado em `portal.html`/`links-ferramentas.html`/`calendario-individual.html`. Tabela **autocontida** (não reaproveita `.pa-table` porque essas 3 páginas não carregam `perfis-acesso.css`). |
| `importacao-plano-saude.css` | `.ips-*` — só usado em `importacao-plano-saude.html`; carrega `perfis-acesso.css` também, pra reaproveitar `.pa-table`/`.pa-tabs`/`.pa-table-wrap` na tabela editável da revisão e nas abas. |
| `custo-contratacao.css` | `.cc-*` — só usado em `custo-contratacao.html`. |
| `indicador-desempenho.css` | `.ind-*` — só usado em `indicador-desempenho.html`; carrega `perfis-acesso.css` também, pelo mesmo motivo de `importacao-plano-saude.css` (tabela/abas de revisão). |
Ao adicionar uma tela nova que precise de modal, reuse `.modal-overlay`/`.modal-card` de `components.css` e só crie estilos de campo próprios se o formulário não for um caso simples de texto/select (que já tem equivalente em `.pa-field` ou `.modal-field`).
## Animações
Três `@keyframes` genéricos em `base.css` (`pidFadeIn`, `pidFadeSlideUp`, `pidScaleIn`) — reutilizados via `animation` (não `transition`) em elementos que entram/saem do layout via `hidden`/`display:none` (modal, dropdown, `.page-content` a cada navegação, `.login-card`), porque só `animation` reinicia sozinho quando um elemento passa de `display:none` para visível; `transition` não anima essa troca (não há frame intermediário). Duração sempre curta (120–200ms) — pedido explícito do usuário: "fluidas, porém rápidas, otimizando o tempo". Botões (`.btn-solid`/`.btn-outline`/`.btn-ghost`/`.btn-danger-outline`/`.icon-btn`) ganharam `transform: scale()` no `:active` como feedback de clique.
**Nenhuma dessas animações respeita `prefers-reduced-motion`** — decisão deliberada do usuário ("as animações devem ignorar a preferência de não mostrar animações ou de acessibilidade do computador do usuário"), não um descuido. Não adicionar um bloco `@media (prefers-reduced-motion: reduce)` desativando isso sem confirmar de novo com o usuário, já que contraria um pedido explícito.

0
config/__init__.py Normal file
View File

7
config/asgi.py Normal file
View File

@ -0,0 +1,7 @@
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_asgi_application()

106
config/settings.py Normal file
View File

@ -0,0 +1,106 @@
import os
from pathlib import Path
from dotenv import load_dotenv
BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(BASE_DIR / ".env")
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "django-insecure-troque-esta-chave-em-producao")
DEBUG = os.environ.get("DJANGO_DEBUG", "True") == "True"
# ALLOWED_HOSTS = [h.strip() for h in os.environ.get("DJANGO_ALLOWED_HOSTS", "localhost,127.0.0.1").split(",")]
ALLOWED_HOSTS = ['*']
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"portal_api",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "config.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "config.wsgi.application"
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ.get("DB_NAME", "portal_de_paula"),
"USER": os.environ.get("DB_USER", "postgres"),
"PASSWORD": os.environ.get("DB_PASSWORD", ""),
"HOST": os.environ.get("DB_HOST", "localhost"),
"PORT": os.environ.get("DB_PORT", "5432"),
}
}
AUTH_USER_MODEL = "portal_api.Usuario"
AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
LANGUAGE_CODE = "pt-br"
TIME_ZONE = "America/Sao_Paulo"
USE_I18N = True
USE_TZ = True
STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles"
# Upload de usuário (hoje só os ícones dos cartões de Links & Ferramentas).
MEDIA_URL = "media/"
MEDIA_ROOT = BASE_DIR / "media"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
}
# Sessão + CSRF: frontend e backend na mesma origem (Django serve os dois),
# então não precisamos de CORS nem de SameSite=None/Secure.
CSRF_COOKIE_HTTPONLY = False
SESSION_COOKIE_SAMESITE = "Lax"
CSRF_COOKIE_SAMESITE = "Lax"

40
config/urls.py Normal file
View File

@ -0,0 +1,40 @@
"""
Além de /api/, este urls.py também serve o frontend (templates/*.html) —
front e back na mesma origem, para autenticação por sessão/cookie funcionar
sem CORS. Os estáticos (static/) são servidos por django.contrib.staticfiles
automaticamente em DEBUG (ver STATICFILES_DIRS em settings.py); em produção,
rode `manage.py collectstatic` e sirva STATIC_ROOT via whitenoise/nginx.
"""
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
from django.views.generic import TemplateView
PAGINAS_FRONTEND = [
"index.html",
"portal.html",
"perfis-acesso.html",
"usuarios.html",
"calendario-individual.html",
"links-ferramentas.html",
"acessos-gerais.html",
"ramais.html",
"importacao-plano-saude.html",
"custo-contratacao.html",
"indicador-desempenho.html",
]
urlpatterns = [
path("admin/", admin.site.urls),
path("api/", include("portal_api.urls")),
path("", TemplateView.as_view(template_name="index.html")),
]
urlpatterns += [
path(pagina, TemplateView.as_view(template_name=pagina)) for pagina in PAGINAS_FRONTEND
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

7
config/wsgi.py Normal file
View File

@ -0,0 +1,7 @@
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
application = get_wsgi_application()

0
database/__init__.py Normal file
View File

100
database/connection.py Normal file
View File

@ -0,0 +1,100 @@
from dataclasses import dataclass, field
from collections.abc import Sequence
from typing import Any, Literal, ClassVar, overload
from sqlalchemy import create_engine, text, Row, RowMapping
from sqlalchemy.engine import Engine
from database.settings import Settings
from database.query import SQLQuery
@dataclass
class DatabaseConnection:
connection: str
engine: Engine = field(init=False)
_settings: ClassVar[Settings] = Settings()
def __post_init__(self) -> None:
self.engine = create_engine(
url=DatabaseConnection._settings.get_url_database(self.connection),
pool_recycle=3600,
pool_pre_ping=True,
echo=False
)
def execute(self, sql: str, params: dict[str, Any] | None = None) -> None:
"""Abre uma transação, executa e commita um INSERT/UPDATE/DELETE sem retorno."""
with self.engine.begin() as conn:
conn.execute(text(sql), params)
def execute_query(self, query: SQLQuery) -> None:
"""Mesmo que execute(), recebendo um SQLQuery em vez de sql/params separados."""
self.execute(query.sql, query.params)
@overload
def select_rows(self, sql: str, params: dict[str, Any] | None = None, *, one: Literal[True]) -> Row[Any] | None: ...
@overload
def select_rows(self, sql: str, params: dict[str, Any] | None = None, *, one: Literal[False] = False) -> Sequence[Row[Any]]: ...
def select_rows(self, sql: str, params: dict[str, Any] | None = None, *, one: bool = False) -> Row[Any] | Sequence[Row[Any]] | None:
"""Abre uma conexão e executa um SELECT que retorna tuplas (Row). \n
Parâmetro one indica se deve retornar um Row ou uma Sequence de Rows."""
with self.engine.connect() as conn:
result = conn.execute(text(sql), params)
return result.fetchone() if one else result.fetchall()
@overload
def select_rows_query(self, query: SQLQuery, *, one: Literal[True]) -> Row[Any] | None: ...
@overload
def select_rows_query(self, query: SQLQuery, *, one: Literal[False] = False) -> Sequence[Row[Any]]: ...
def select_rows_query(self, query: SQLQuery, *, one: bool = False) -> Row[Any] | Sequence[Row[Any]] | None:
"""Mesmo que select_rows(), recebendo um SQLQuery em vez de sql/params separados."""
return self.select_rows(query.sql, query.params, one=one)
@overload
def select_mappings(self, sql: str, params: dict[str, Any] | None = None, *, one: Literal[True]) -> RowMapping | None: ...
@overload
def select_mappings(self, sql: str, params: dict[str, Any] | None = None, *, one: Literal[False] = False) -> Sequence[RowMapping]: ...
def select_mappings(self, sql: str, params: dict[str, Any] | None = None, *, one: bool = False) -> RowMapping | Sequence[RowMapping] | None:
"""Abre uma conexão e executa um SELECT que retorna dicionários (RowMapping). \n
Parâmetro one indica se deve retornar um Row ou uma Sequence de Rows."""
with self.engine.connect() as conn:
result = conn.execute(text(sql), params).mappings()
return result.fetchone() if one else result.fetchall()
@overload
def select_mappings_query(self, query: SQLQuery, *, one: Literal[True]) -> RowMapping | None: ...
@overload
def select_mappings_query(self, query: SQLQuery, *, one: Literal[False] = False) -> Sequence[RowMapping]: ...
def select_mappings_query(self, query: SQLQuery, *, one: bool = False) -> RowMapping | Sequence[RowMapping] | None:
"""Mesmo que select_mappings(), recebendo um SQLQuery em vez de sql/params separados."""
return self.select_mappings(query.sql, query.params, one=one)
@overload
def execute_returning(self, sql: str, params: dict[str, Any] | None = None, *, one: Literal[True]) -> Row[Any] | None: ...
@overload
def execute_returning(self, sql: str, params: dict[str, Any] | None = None, *, one: Literal[False] = False) -> Sequence[Row[Any]]: ...
def execute_returning(self, sql: str, params: dict[str, Any] | None = None, *, one: bool = False) -> Row[Any] | Sequence[Row[Any]] | None:
"""Abre uma transação, executa e commita um INSERT/UPDATE/DELETE com retorno."""
with self.engine.begin() as conn:
result = conn.execute(text(sql), params)
return result.fetchone() if one else result.fetchall()
@overload
def execute_returning_query(self, query: SQLQuery, *, one: Literal[True]) -> Row[Any] | None: ...
@overload
def execute_returning_query(self, query: SQLQuery, *, one: Literal[False] = False) -> Sequence[Row[Any]]: ...
def execute_returning_query(self, query: SQLQuery, *, one: bool = False) -> Row[Any] | Sequence[Row[Any]] | None:
"""Mesmo que execute_returning(), recebendo um SQLQuery em vez de sql/params separados."""
return self.execute_returning(query.sql, query.params, one=one)
def close(self) -> None:
"""Fecha o pool de conexões do engine."""
self.engine.dispose()
def __enter__(self) -> "DatabaseConnection":
return self
def __exit__(self, *exc_info) -> None:
self.close()

7
database/query.py Normal file
View File

@ -0,0 +1,7 @@
from dataclasses import dataclass, field
from typing import Any
@dataclass(slots=True, frozen=True)
class SQLQuery:
sql: str
params: dict[str, Any] = field(default_factory=dict)

64
database/settings.py Normal file
View File

@ -0,0 +1,64 @@
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
from pydantic import BaseModel, Field, field_validator, ValidationError, SecretStr
from sqlalchemy.engine import URL
BASE_DIR = Path(__file__).resolve().parents[2]
ENV_FILE_PATH = BASE_DIR / ".env"
SUPPORTED_DRIVERS = {
"postgresql": "postgresql+psycopg2",
"mysql": "mysql+pymysql",
"sqlserver": "mssql+pyodbc",
"sqlite": "sqlite"
}
class DatabaseConfig(BaseModel):
user: str
password: SecretStr
host: str
port: int
database: str
driver: str
@field_validator("driver")
def validate_driver(cls, v):
if v not in SUPPORTED_DRIVERS:
raise ValueError(f"Driver '{v}' não suportado. Use um de: {list(SUPPORTED_DRIVERS.keys())}")
return v
def sqlalchemy_url(self) -> URL:
drivername = SUPPORTED_DRIVERS[self.driver]
return URL.create(
drivername=drivername,
username=self.user,
password=self.password.get_secret_value(),
host=self.host,
port=self.port,
database=self.database,
)
class DatabaseSettings(BaseSettings):
database: dict[str, DatabaseConfig]
model_config = SettingsConfigDict(
env_file=ENV_FILE_PATH,
env_file_encoding="utf-8",
env_nested_delimiter="__",
extra="ignore"
)
class Settings:
databases = DatabaseSettings()
def get_url_database(self, database: str) -> URL:
try:
return self.databases.database[database].sqlalchemy_url()
except KeyError as e:
raise ValueError(f"Database '{database}' não encontrado. Use um de: {list(self.databases.database.keys())}")
def get_url_databases(self) -> dict[str, URL]:
return {
name: config.sqlalchemy_url() for name, config in self.databases.database.items()
}

20
manage.py Normal file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
"""Utilitário de linha de comando do Django para tarefas administrativas."""
import os
import sys
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Não foi possível importar o Django. Ele está instalado e disponível na "
"variável de ambiente PYTHONPATH? Você esqueceu de ativar um ambiente virtual?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()

View File

@ -0,0 +1 @@
x

View File

@ -0,0 +1 @@
x

Binary file not shown.

View File

@ -0,0 +1 @@
x

View File

@ -0,0 +1 @@
x

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -0,0 +1,67 @@
Cód. Contr/Contrat. Pagador;Id. Título;Número Título;Valor Bruto;Valor Líquido;Situação Título;Contratante;Id. Titular;Família;Id. Benef.;Cód.Beneficiário;Nome Beneficiário;Tipo Benef.;Grau Depend.;Código Combinação;Reservado;Valor;Competência;Tipo;Tipo Ato Médico;Cód. Serviço;Descrição Serviço
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;757515;'9750167003394433;MARCOS AURELIO FABRIN;1;0 - TITULAR;10002;;177,85;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;195,82;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;50;jul/26;Serviços ;Consulta;10101012;Consulta em consultorio no horario normal ou preestabelecido
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;50;jul/26;Serviços ;Consulta;10102504;CONSULTA ELETIVA ENDOCRINOLOGIA - CEM FOZ
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;6,19;jul/26;Serviços ;Exame;40310213;Cultura, urina com contagem de colonias
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;2,48;jul/26;Serviços ;Exame;40311210;Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;8,05;jul/26;Serviços ;Exame;40316289;Foliculo estimulante, hormonio FSH - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;7,8;jul/26;Serviços ;Exame;40316335;Hormonio luteinizante LH - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;13,62;jul/26;Serviços ;Exame;40316459;Sulfato de dehidroepiandrosterona S-DHEA - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;18,58;jul/26;Serviços ;Exame;40316505;Testosterona livre - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;13,01;jul/26;Serviços ;Exame;40316513;Testosterona total - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;751229;'9750167003394450;CRISTINA PEREIRA MORENO FABRIN;2;1 - CONJUGE;10220;;139,54;jul/26;Serviços ;Exame;40601293;Procedimento diagnostico por captura hibrida
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;765519;'9750167003780007;EDUARDA VALENTINA FABRIN;2;10 - FILHO(A);10002;;113,9;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;765519;'9750167003780007;EDUARDA VALENTINA FABRIN;2;10 - FILHO(A);10002;;1,74;jul/26;Serviços ;Exame;40301630;Creatinina - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;765519;'9750167003780007;EDUARDA VALENTINA FABRIN;2;10 - FILHO(A);10002;;3,72;jul/26;Serviços ;Exame;40304361;Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;765519;'9750167003780007;EDUARDA VALENTINA FABRIN;2;10 - FILHO(A);10002;;6,19;jul/26;Serviços ;Exame;40310213;Cultura, urina com contagem de colonias
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;765519;'9750167003780007;EDUARDA VALENTINA FABRIN;2;10 - FILHO(A);10002;;2,48;jul/26;Serviços ;Exame;40310418;Antibiograma teste de sensibilidade e antibioticos e quimioterapicos, por bact
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;757515;MARCOS AURELIO FABRIN - 832585;765519;'9750167003780007;EDUARDA VALENTINA FABRIN;2;10 - FILHO(A);10002;;2,48;jul/26;Serviços ;Exame;40311210;Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;751302;LEANDRO MARAFON ALVES - 832941;751302;'9750167003423980;LEANDRO MARAFON ALVES;1;0 - TITULAR;10002;;177,85;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;751302;LEANDRO MARAFON ALVES - 832941;751303;'9750167003423999;ALINE RAMOS DO NASCIMENTO MARAFON;2;1 - CONJUGE;10220;;195,82;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;751302;LEANDRO MARAFON ALVES - 832941;762343;'9750167003601226;LORENA DO NASCIMENTO MARAFON ALVES;2;10 - FILHO(A);10002;;113,9;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;751302;LEANDRO MARAFON ALVES - 832941;763663;'9750167003674223;LEONARDO DO NASCIMENTO MARAFON ALVES;2;10 - FILHO(A);10002;;113,9;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;767220;MATHEUS PRESCINOTTI - 836243;767220;'9750167003680177;MATHEUS PRESCINOTTI;1;0 - TITULAR;10002;;159,87;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;759518;'9750167003742768;MAURICIO FABRIN;1;0 - TITULAR;10002;;143,88;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;759518;'9750167003742768;MAURICIO FABRIN;1;0 - TITULAR;10002;;50;jul/26;Serviços ;Consulta;10101012;Consulta em consultorio no horario normal ou preestabelecido
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;759518;'9750167003742768;MAURICIO FABRIN;1;0 - TITULAR;10002;;69,77;jul/26;Serviços ;Exame;40901106;Ecodopplercardiograma transtoracico
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;763713;'9750167003744671;RUBIA MILENA MIGLIOLI REIS;2;1 - CONJUGE;10220;;144,27;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;767370;'9750167003795080;ELOAH VITORIA MIGLIOLI FABRIN;2;10 - FILHO(A);10002;;113,9;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;846589;'9750167018776477;SAMUEL MIGLIOLI FABRIN;2;10 - FILHO(A);10220;;121,89;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759518;MAURICIO FABRIN - 837231;846589;'9750167018776477;SAMUEL MIGLIOLI FABRIN;2;10 - FILHO(A);10220;;69,77;jul/26;Serviços ;Consulta;10106146;Atendimento ambulatorial em puericultura com diretriz clinica definida pela ANS
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759987;JEAN RUBEN SOUZA JARA - 837371;759987;'9750167003751279;JEAN RUBEN SOUZA JARA;1;0 - TITULAR;10002;;497,6;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759987;JEAN RUBEN SOUZA JARA - 837371;759988;'9750167003751287;PATRICIA VALESKA FOTIADIS HENRIQUES JARA;2;1 - CONJUGE;10002;;497,6;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;759987;JEAN RUBEN SOUZA JARA - 837371;760022;'9750167003751295;GIOVANNA FOTIADIS HENRIQUES JARA;2;10 - FILHO(A);10002;;113,9;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762851;'9750167003776174;VALDECIR PROVIN;1;0 - TITULAR;10002;;621,51;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;283,78;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;1,74;jul/26;Serviços ;Exame;40301060;Acido ascorbico vitamina C - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;3,72;jul/26;Serviços ;Exame;40301583;Colesterol HDL - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;4,96;jul/26;Serviços ;Exame;40301591;Colesterol LDL - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;1,74;jul/26;Serviços ;Exame;40301605;Colesterol total - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;2,23;jul/26;Serviços ;Exame;40301842;Ferro serico - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;1,74;jul/26;Serviços ;Exame;40302040;Glicose - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;8,4;jul/26;Serviços ;Exame;40302075;Hemoglobina glicada A1 total - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;1,98;jul/26;Serviços ;Exame;40302237;Magnesio - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;8,28;jul/26;Serviços ;Exame;40302830;Vitamina D 25 HIDROXI, pesquisa e/ou dosagem Vitamina D3
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;3,72;jul/26;Serviços ;Exame;40304361;Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;6,19;jul/26;Serviços ;Exame;40310213;Cultura, urina com contagem de colonias
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;2,48;jul/26;Serviços ;Exame;40311210;Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;14,86;jul/26;Serviços ;Exame;40313328;Zinco - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;19,82;jul/26;Serviços ;Exame;40316076;Androstenediona - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;9,29;jul/26;Serviços ;Exame;40316190;Cortisol - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;12,39;jul/26;Serviços ;Exame;40316246;Estradiol - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;15,48;jul/26;Serviços ;Exame;40316270;Ferritina - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;8,05;jul/26;Serviços ;Exame;40316289;Foliculo estimulante, hormonio FSH - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;7,8;jul/26;Serviços ;Exame;40316335;Hormonio luteinizante LH - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;6,81;jul/26;Serviços ;Exame;40316360;Insulina - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;10,53;jul/26;Serviços ;Exame;40316416;Prolactina - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;10,53;jul/26;Serviços ;Exame;40316491;T4 livre - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;18,58;jul/26;Serviços ;Exame;40316505;Testosterona livre - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;10,53;jul/26;Serviços ;Exame;40316521;Tireoestimulante, hormonio TSH - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762852;'9750167003776182;SUZANA DE ALMEIDA;2;1 - CONJUGE;10002;;10,53;jul/26;Serviços ;Exame;40316572;Vitamina B12 - pesquisa e/ou dosagem
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762853;'9750167003776190;MAURICIO PROVIN NETO;2;10 - FILHO(A);10002;;143,88;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;762851;VALDECIR PROVIN - 837851;762853;'9750167003776190;MAURICIO PROVIN NETO;2;10 - FILHO(A);10002;;69,77;jul/26;Serviços ;Consulta;10101039;Consulta em pronto socorro
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;764799;ENALTO FERREIRA MIRANDA - 837889;764799;'9750167003777987;ENALTO FERREIRA MIRANDA;1;0 - TITULAR;10002;;683,47;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;764799;ENALTO FERREIRA MIRANDA - 837889;764799;'9750167003777987;ENALTO FERREIRA MIRANDA;1;0 - TITULAR;10002;;50;jul/26;Serviços ;Consulta;10101012;Consulta em consultorio no horario normal ou preestabelecido
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;764799;ENALTO FERREIRA MIRANDA - 837889;764800;'9750167003777995;ELAINE LIMA MIRANDA;2;10 - FILHO(A);10220;;195,82;jul/26;Mensalidade;;;
5880360-0;3151518;201924969;5807,85;5807,85;Aberto;PRESCINOTTI & CIA LTDA - 77307387000158;764799;ENALTO FERREIRA MIRANDA - 837889;766687;'9750167003804380;EDERSON LIMA MIRANDA;2;10 - FILHO(A);10002;;159,87;jul/26;Mensalidade;;;
1 Cód. Contr/Contrat. Pagador Id. Título Número Título Valor Bruto Valor Líquido Situação Título Contratante Id. Titular Família Id. Benef. Cód.Beneficiário Nome Beneficiário Tipo Benef. Grau Depend. Código Combinação Reservado Valor Competência Tipo Tipo Ato Médico Cód. Serviço Descrição Serviço
2 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 757515 '9750167003394433 MARCOS AURELIO FABRIN 1 0 - TITULAR 10002 177,85 jul/26 Mensalidade
3 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 195,82 jul/26 Mensalidade
4 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 50 jul/26 Serviços Consulta 10101012 Consulta em consultorio no horario normal ou preestabelecido
5 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 50 jul/26 Serviços Consulta 10102504 CONSULTA ELETIVA ENDOCRINOLOGIA - CEM FOZ
6 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 6,19 jul/26 Serviços Exame 40310213 Cultura, urina com contagem de colonias
7 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 2,48 jul/26 Serviços Exame 40311210 Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
8 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 8,05 jul/26 Serviços Exame 40316289 Foliculo estimulante, hormonio FSH - pesquisa e/ou dosagem
9 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 7,8 jul/26 Serviços Exame 40316335 Hormonio luteinizante LH - pesquisa e/ou dosagem
10 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 13,62 jul/26 Serviços Exame 40316459 Sulfato de dehidroepiandrosterona S-DHEA - pesquisa e/ou dosagem
11 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 18,58 jul/26 Serviços Exame 40316505 Testosterona livre - pesquisa e/ou dosagem
12 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 13,01 jul/26 Serviços Exame 40316513 Testosterona total - pesquisa e/ou dosagem
13 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 751229 '9750167003394450 CRISTINA PEREIRA MORENO FABRIN 2 1 - CONJUGE 10220 139,54 jul/26 Serviços Exame 40601293 Procedimento diagnostico por captura hibrida
14 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 765519 '9750167003780007 EDUARDA VALENTINA FABRIN 2 10 - FILHO(A) 10002 113,9 jul/26 Mensalidade
15 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 765519 '9750167003780007 EDUARDA VALENTINA FABRIN 2 10 - FILHO(A) 10002 1,74 jul/26 Serviços Exame 40301630 Creatinina - pesquisa e/ou dosagem
16 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 765519 '9750167003780007 EDUARDA VALENTINA FABRIN 2 10 - FILHO(A) 10002 3,72 jul/26 Serviços Exame 40304361 Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
17 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 765519 '9750167003780007 EDUARDA VALENTINA FABRIN 2 10 - FILHO(A) 10002 6,19 jul/26 Serviços Exame 40310213 Cultura, urina com contagem de colonias
18 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 765519 '9750167003780007 EDUARDA VALENTINA FABRIN 2 10 - FILHO(A) 10002 2,48 jul/26 Serviços Exame 40310418 Antibiograma teste de sensibilidade e antibioticos e quimioterapicos, por bact
19 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 757515 MARCOS AURELIO FABRIN - 832585 765519 '9750167003780007 EDUARDA VALENTINA FABRIN 2 10 - FILHO(A) 10002 2,48 jul/26 Serviços Exame 40311210 Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
20 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 751302 LEANDRO MARAFON ALVES - 832941 751302 '9750167003423980 LEANDRO MARAFON ALVES 1 0 - TITULAR 10002 177,85 jul/26 Mensalidade
21 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 751302 LEANDRO MARAFON ALVES - 832941 751303 '9750167003423999 ALINE RAMOS DO NASCIMENTO MARAFON 2 1 - CONJUGE 10220 195,82 jul/26 Mensalidade
22 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 751302 LEANDRO MARAFON ALVES - 832941 762343 '9750167003601226 LORENA DO NASCIMENTO MARAFON ALVES 2 10 - FILHO(A) 10002 113,9 jul/26 Mensalidade
23 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 751302 LEANDRO MARAFON ALVES - 832941 763663 '9750167003674223 LEONARDO DO NASCIMENTO MARAFON ALVES 2 10 - FILHO(A) 10002 113,9 jul/26 Mensalidade
24 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 767220 MATHEUS PRESCINOTTI - 836243 767220 '9750167003680177 MATHEUS PRESCINOTTI 1 0 - TITULAR 10002 159,87 jul/26 Mensalidade
25 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 759518 '9750167003742768 MAURICIO FABRIN 1 0 - TITULAR 10002 143,88 jul/26 Mensalidade
26 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 759518 '9750167003742768 MAURICIO FABRIN 1 0 - TITULAR 10002 50 jul/26 Serviços Consulta 10101012 Consulta em consultorio no horario normal ou preestabelecido
27 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 759518 '9750167003742768 MAURICIO FABRIN 1 0 - TITULAR 10002 69,77 jul/26 Serviços Exame 40901106 Ecodopplercardiograma transtoracico
28 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 763713 '9750167003744671 RUBIA MILENA MIGLIOLI REIS 2 1 - CONJUGE 10220 144,27 jul/26 Mensalidade
29 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 767370 '9750167003795080 ELOAH VITORIA MIGLIOLI FABRIN 2 10 - FILHO(A) 10002 113,9 jul/26 Mensalidade
30 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 846589 '9750167018776477 SAMUEL MIGLIOLI FABRIN 2 10 - FILHO(A) 10220 121,89 jul/26 Mensalidade
31 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759518 MAURICIO FABRIN - 837231 846589 '9750167018776477 SAMUEL MIGLIOLI FABRIN 2 10 - FILHO(A) 10220 69,77 jul/26 Serviços Consulta 10106146 Atendimento ambulatorial em puericultura com diretriz clinica definida pela ANS
32 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759987 JEAN RUBEN SOUZA JARA - 837371 759987 '9750167003751279 JEAN RUBEN SOUZA JARA 1 0 - TITULAR 10002 497,6 jul/26 Mensalidade
33 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759987 JEAN RUBEN SOUZA JARA - 837371 759988 '9750167003751287 PATRICIA VALESKA FOTIADIS HENRIQUES JARA 2 1 - CONJUGE 10002 497,6 jul/26 Mensalidade
34 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 759987 JEAN RUBEN SOUZA JARA - 837371 760022 '9750167003751295 GIOVANNA FOTIADIS HENRIQUES JARA 2 10 - FILHO(A) 10002 113,9 jul/26 Mensalidade
35 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762851 '9750167003776174 VALDECIR PROVIN 1 0 - TITULAR 10002 621,51 jul/26 Mensalidade
36 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 283,78 jul/26 Mensalidade
37 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 1,74 jul/26 Serviços Exame 40301060 Acido ascorbico vitamina C - pesquisa e/ou dosagem
38 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 3,72 jul/26 Serviços Exame 40301583 Colesterol HDL - pesquisa e/ou dosagem
39 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 4,96 jul/26 Serviços Exame 40301591 Colesterol LDL - pesquisa e/ou dosagem
40 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 1,74 jul/26 Serviços Exame 40301605 Colesterol total - pesquisa e/ou dosagem
41 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 2,23 jul/26 Serviços Exame 40301842 Ferro serico - pesquisa e/ou dosagem
42 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 1,74 jul/26 Serviços Exame 40302040 Glicose - pesquisa e/ou dosagem
43 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 8,4 jul/26 Serviços Exame 40302075 Hemoglobina glicada A1 total - pesquisa e/ou dosagem
44 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 1,98 jul/26 Serviços Exame 40302237 Magnesio - pesquisa e/ou dosagem
45 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 8,28 jul/26 Serviços Exame 40302830 Vitamina D 25 HIDROXI, pesquisa e/ou dosagem Vitamina D3
46 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 3,72 jul/26 Serviços Exame 40304361 Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
47 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 6,19 jul/26 Serviços Exame 40310213 Cultura, urina com contagem de colonias
48 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 2,48 jul/26 Serviços Exame 40311210 Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
49 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 14,86 jul/26 Serviços Exame 40313328 Zinco - pesquisa e/ou dosagem
50 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 19,82 jul/26 Serviços Exame 40316076 Androstenediona - pesquisa e/ou dosagem
51 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 9,29 jul/26 Serviços Exame 40316190 Cortisol - pesquisa e/ou dosagem
52 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 12,39 jul/26 Serviços Exame 40316246 Estradiol - pesquisa e/ou dosagem
53 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 15,48 jul/26 Serviços Exame 40316270 Ferritina - pesquisa e/ou dosagem
54 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 8,05 jul/26 Serviços Exame 40316289 Foliculo estimulante, hormonio FSH - pesquisa e/ou dosagem
55 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 7,8 jul/26 Serviços Exame 40316335 Hormonio luteinizante LH - pesquisa e/ou dosagem
56 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 6,81 jul/26 Serviços Exame 40316360 Insulina - pesquisa e/ou dosagem
57 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 10,53 jul/26 Serviços Exame 40316416 Prolactina - pesquisa e/ou dosagem
58 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 10,53 jul/26 Serviços Exame 40316491 T4 livre - pesquisa e/ou dosagem
59 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 18,58 jul/26 Serviços Exame 40316505 Testosterona livre - pesquisa e/ou dosagem
60 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 10,53 jul/26 Serviços Exame 40316521 Tireoestimulante, hormonio TSH - pesquisa e/ou dosagem
61 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762852 '9750167003776182 SUZANA DE ALMEIDA 2 1 - CONJUGE 10002 10,53 jul/26 Serviços Exame 40316572 Vitamina B12 - pesquisa e/ou dosagem
62 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762853 '9750167003776190 MAURICIO PROVIN NETO 2 10 - FILHO(A) 10002 143,88 jul/26 Mensalidade
63 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 762851 VALDECIR PROVIN - 837851 762853 '9750167003776190 MAURICIO PROVIN NETO 2 10 - FILHO(A) 10002 69,77 jul/26 Serviços Consulta 10101039 Consulta em pronto socorro
64 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 764799 ENALTO FERREIRA MIRANDA - 837889 764799 '9750167003777987 ENALTO FERREIRA MIRANDA 1 0 - TITULAR 10002 683,47 jul/26 Mensalidade
65 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 764799 ENALTO FERREIRA MIRANDA - 837889 764799 '9750167003777987 ENALTO FERREIRA MIRANDA 1 0 - TITULAR 10002 50 jul/26 Serviços Consulta 10101012 Consulta em consultorio no horario normal ou preestabelecido
66 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 764799 ENALTO FERREIRA MIRANDA - 837889 764800 '9750167003777995 ELAINE LIMA MIRANDA 2 10 - FILHO(A) 10220 195,82 jul/26 Mensalidade
67 5880360-0 3151518 201924969 5807,85 5807,85 Aberto PRESCINOTTI & CIA LTDA - 77307387000158 764799 ENALTO FERREIRA MIRANDA - 837889 766687 '9750167003804380 EDERSON LIMA MIRANDA 2 10 - FILHO(A) 10002 159,87 jul/26 Mensalidade

View File

@ -0,0 +1,82 @@
Cód. Contr/Contrat. Pagador;Id. Título;Número Título;Valor Bruto;Valor Líquido;Situação Título;Contratante;Id. Titular;Família;Id. Benef.;Cód.Beneficiário;Nome Beneficiário;Tipo Benef.;Grau Depend.;Código Combinação;Reservado;Valor;Competência;Tipo;Tipo Ato Médico;Cód. Serviço;Descrição Serviço
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;318,03;07/2026;Mensalidade;;;
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301150;Acido urico - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301400;Calcio - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;14,86;07/2026;Serviços ;Exame;40301567;Cobre - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;3,72;07/2026;Serviços ;Exame;40301583;Colesterol HDL - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;4,96;07/2026;Serviços ;Exame;40301591;Colesterol LDL - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301630;Creatinina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;2,23;07/2026;Serviços ;Exame;40301842;Ferro serico - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302040;Glicose - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;8,4;07/2026;Serviços ;Exame;40302075;Hemoglobina glicada A1 total - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,98;07/2026;Serviços ;Exame;40302237;Magnesio - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302504;Transaminase oxalacetica amino transferase aspartato - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302512;Transaminase piruvica amino transferase de alanina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;2,48;07/2026;Serviços ;Exame;40302547;Triglicerideos - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302580;Ureia - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;8,8;07/2026;Serviços ;Exame;40302601;Vitamina A, pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;8,28;07/2026;Serviços ;Exame;40302830;Vitamina D 25 HIDROXI, pesquisa e/ou dosagem Vitamina D3
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;3,72;07/2026;Serviços ;Exame;40304361;Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;24,77;07/2026;Serviços ;Exame;40305465;Paratormonio - PTH ou fracao cada - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;14,86;07/2026;Serviços ;Exame;40313328;Zinco - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;9,29;07/2026;Serviços ;Exame;40316190;Cortisol - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;12,39;07/2026;Serviços ;Exame;40316246;Estradiol - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;15,48;07/2026;Serviços ;Exame;40316270;Ferritina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;8,05;07/2026;Serviços ;Exame;40316289;Foliculo estimulante, hormonio FSH - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;25,76;07/2026;Serviços ;Exame;40316300;Globulina de ligacao de hormonios sexuais SHBG - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;7,8;07/2026;Serviços ;Exame;40316335;Hormonio luteinizante LH - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;6,81;07/2026;Serviços ;Exame;40316360;Insulina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;13,01;07/2026;Serviços ;Exame;40316408;Progesterona - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316416;Prolactina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316491;T4 livre - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;18,58;07/2026;Serviços ;Exame;40316505;Testosterona livre - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;13,01;07/2026;Serviços ;Exame;40316513;Testosterona total - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316521;Tireoestimulante, hormonio TSH - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;8,05;07/2026;Serviços ;Exame;40316556;Triiodotironina T3 - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765929;'9750167003795578;TATIANE WELTER MACHADO DE CARVALHO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316572;Vitamina B12 - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765911;'9750167003795594;ALEXANDRE DE CARVALHO;2;1 - CONJUGE;10080;;228,72;07/2026;Mensalidade;;;
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765929;TATIANE WELTER MACHADO DE CARVALHO - 838206;765914;'9750167003795624;HELOISA MACHADO DE CARVALHO;2;10 - FILHO(A);10080;;129,61;07/2026;Mensalidade;;;
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;541,31;07/2026;Mensalidade;;;
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301060;Acido ascorbico vitamina C - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40301087;Acido folico, pesquisa e/ou dosagem nos eritrocitos
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301150;Acido urico - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,86;07/2026;Serviços ;Exame;40301397;Bilirrubinas direta, indireta e total - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301400;Calcio - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;4,96;07/2026;Serviços ;Exame;40301419;Calcio ionico - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301427;Capacidade de fixacao de ferro - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;3,72;07/2026;Serviços ;Exame;40301583;Colesterol HDL - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;4,96;07/2026;Serviços ;Exame;40301591;Colesterol LDL - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301605;Colesterol total - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40301630;Creatinina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;2,48;07/2026;Serviços ;Exame;40301990;Gama-glutamil transferase - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302040;Glicose - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;8,4;07/2026;Serviços ;Exame;40302075;Hemoglobina glicada A1 total - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;24,77;07/2026;Serviços ;Exame;40302113;Homocisteina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,98;07/2026;Serviços ;Exame;40302237;Magnesio - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302504;Transaminase oxalacetica amino transferase aspartato - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302512;Transaminase piruvica amino transferase de alanina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;2,48;07/2026;Serviços ;Exame;40302547;Triglicerideos - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;1,74;07/2026;Serviços ;Exame;40302580;Ureia - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;8,28;07/2026;Serviços ;Exame;40302830;Vitamina D 25 HIDROXI, pesquisa e/ou dosagem Vitamina D3
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;3,72;07/2026;Serviços ;Exame;40304361;Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;8,3;07/2026;Serviços ;Exame;40308391;Proteina C reativa, quantitativa - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;2,48;07/2026;Serviços ;Exame;40311210;Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;14,86;07/2026;Serviços ;Exame;40313328;Zinco - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;15,48;07/2026;Serviços ;Exame;40316270;Ferritina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;25,76;07/2026;Serviços ;Exame;40316300;Globulina de ligacao de hormonios sexuais SHBG - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;6,81;07/2026;Serviços ;Exame;40316360;Insulina - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316467;T3 livre - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316491;T4 livre - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;18,58;07/2026;Serviços ;Exame;40316505;Testosterona livre - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;13,01;07/2026;Serviços ;Exame;40316513;Testosterona total - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316521;Tireoestimulante, hormonio TSH - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765930;'9750167003795586;LAERCIO WELTER MACHADO;1;0 - TITULAR;10080;;10,53;07/2026;Serviços ;Exame;40316572;Vitamina B12 - pesquisa e/ou dosagem
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;541,31;07/2026;Mensalidade;;;
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;16,68;07/2026;Serviços ;Exame;40805026;RX - Torax - 2 incidencias
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;77,72;07/2026;Serviços ;Exame;40808041;Mamografia digital bilateral com diretriz definida pela ANS - n 52
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;59,76;07/2026;Serviços ;Exame;40808130;Densitometria ossea - rotina: coluna e femur ou dois segmentos
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;38,52;07/2026;Serviços ;Exame;40901114;US - Mamas
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;78,49;07/2026;Serviços ;Exame;40901122;US - Abdome total abdome superior, rins, bexiga, aorta, veia cava inferior e ad
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;39,43;07/2026;Serviços ;Exame;40901203;US - Orgaos superficiais tireoide ou escroto ou penis ou cranio
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765912;'9750167003795608;ALESSANDRA APARECIDA WESTENBERGER MACHADO;2;1 - CONJUGE;10080;;44,36;07/2026;Serviços ;Exame;40901300;US - Transvaginal utero, ovario, anexos e vagina
5855250-0;3151388;201924839;2778,08;2778,08;Aberto;CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113;765930;LAERCIO WELTER MACHADO - 838207;765913;'9750167003795616;MATHEUS WESTENBERGER MACHADO;2;10 - FILHO(A);10080;;129,61;07/2026;Mensalidade;;;
1 Cód. Contr/Contrat. Pagador Id. Título Número Título Valor Bruto Valor Líquido Situação Título Contratante Id. Titular Família Id. Benef. Cód.Beneficiário Nome Beneficiário Tipo Benef. Grau Depend. Código Combinação Reservado Valor Competência Tipo Tipo Ato Médico Cód. Serviço Descrição Serviço
2 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 318,03 07/2026 Mensalidade
3 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301150 Acido urico - pesquisa e/ou dosagem
4 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301400 Calcio - pesquisa e/ou dosagem
5 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 14,86 07/2026 Serviços Exame 40301567 Cobre - pesquisa e/ou dosagem
6 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 3,72 07/2026 Serviços Exame 40301583 Colesterol HDL - pesquisa e/ou dosagem
7 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 4,96 07/2026 Serviços Exame 40301591 Colesterol LDL - pesquisa e/ou dosagem
8 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301630 Creatinina - pesquisa e/ou dosagem
9 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 2,23 07/2026 Serviços Exame 40301842 Ferro serico - pesquisa e/ou dosagem
10 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302040 Glicose - pesquisa e/ou dosagem
11 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 8,4 07/2026 Serviços Exame 40302075 Hemoglobina glicada A1 total - pesquisa e/ou dosagem
12 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,98 07/2026 Serviços Exame 40302237 Magnesio - pesquisa e/ou dosagem
13 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302504 Transaminase oxalacetica amino transferase aspartato - pesquisa e/ou dosagem
14 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302512 Transaminase piruvica amino transferase de alanina - pesquisa e/ou dosagem
15 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 2,48 07/2026 Serviços Exame 40302547 Triglicerideos - pesquisa e/ou dosagem
16 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302580 Ureia - pesquisa e/ou dosagem
17 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 8,8 07/2026 Serviços Exame 40302601 Vitamina A, pesquisa e/ou dosagem
18 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 8,28 07/2026 Serviços Exame 40302830 Vitamina D 25 HIDROXI, pesquisa e/ou dosagem Vitamina D3
19 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 3,72 07/2026 Serviços Exame 40304361 Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
20 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 24,77 07/2026 Serviços Exame 40305465 Paratormonio - PTH ou fracao cada - pesquisa e/ou dosagem
21 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 14,86 07/2026 Serviços Exame 40313328 Zinco - pesquisa e/ou dosagem
22 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 9,29 07/2026 Serviços Exame 40316190 Cortisol - pesquisa e/ou dosagem
23 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 12,39 07/2026 Serviços Exame 40316246 Estradiol - pesquisa e/ou dosagem
24 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 15,48 07/2026 Serviços Exame 40316270 Ferritina - pesquisa e/ou dosagem
25 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 8,05 07/2026 Serviços Exame 40316289 Foliculo estimulante, hormonio FSH - pesquisa e/ou dosagem
26 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 25,76 07/2026 Serviços Exame 40316300 Globulina de ligacao de hormonios sexuais SHBG - pesquisa e/ou dosagem
27 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 7,8 07/2026 Serviços Exame 40316335 Hormonio luteinizante LH - pesquisa e/ou dosagem
28 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 6,81 07/2026 Serviços Exame 40316360 Insulina - pesquisa e/ou dosagem
29 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 13,01 07/2026 Serviços Exame 40316408 Progesterona - pesquisa e/ou dosagem
30 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316416 Prolactina - pesquisa e/ou dosagem
31 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316491 T4 livre - pesquisa e/ou dosagem
32 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 18,58 07/2026 Serviços Exame 40316505 Testosterona livre - pesquisa e/ou dosagem
33 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 13,01 07/2026 Serviços Exame 40316513 Testosterona total - pesquisa e/ou dosagem
34 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316521 Tireoestimulante, hormonio TSH - pesquisa e/ou dosagem
35 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 8,05 07/2026 Serviços Exame 40316556 Triiodotironina T3 - pesquisa e/ou dosagem
36 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765929 '9750167003795578 TATIANE WELTER MACHADO DE CARVALHO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316572 Vitamina B12 - pesquisa e/ou dosagem
37 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765911 '9750167003795594 ALEXANDRE DE CARVALHO 2 1 - CONJUGE 10080 228,72 07/2026 Mensalidade
38 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765929 TATIANE WELTER MACHADO DE CARVALHO - 838206 765914 '9750167003795624 HELOISA MACHADO DE CARVALHO 2 10 - FILHO(A) 10080 129,61 07/2026 Mensalidade
39 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 541,31 07/2026 Mensalidade
40 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301060 Acido ascorbico vitamina C - pesquisa e/ou dosagem
41 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40301087 Acido folico, pesquisa e/ou dosagem nos eritrocitos
42 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301150 Acido urico - pesquisa e/ou dosagem
43 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,86 07/2026 Serviços Exame 40301397 Bilirrubinas direta, indireta e total - pesquisa e/ou dosagem
44 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301400 Calcio - pesquisa e/ou dosagem
45 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 4,96 07/2026 Serviços Exame 40301419 Calcio ionico - pesquisa e/ou dosagem
46 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301427 Capacidade de fixacao de ferro - pesquisa e/ou dosagem
47 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 3,72 07/2026 Serviços Exame 40301583 Colesterol HDL - pesquisa e/ou dosagem
48 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 4,96 07/2026 Serviços Exame 40301591 Colesterol LDL - pesquisa e/ou dosagem
49 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301605 Colesterol total - pesquisa e/ou dosagem
50 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40301630 Creatinina - pesquisa e/ou dosagem
51 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 2,48 07/2026 Serviços Exame 40301990 Gama-glutamil transferase - pesquisa e/ou dosagem
52 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302040 Glicose - pesquisa e/ou dosagem
53 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 8,4 07/2026 Serviços Exame 40302075 Hemoglobina glicada A1 total - pesquisa e/ou dosagem
54 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 24,77 07/2026 Serviços Exame 40302113 Homocisteina - pesquisa e/ou dosagem
55 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,98 07/2026 Serviços Exame 40302237 Magnesio - pesquisa e/ou dosagem
56 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302504 Transaminase oxalacetica amino transferase aspartato - pesquisa e/ou dosagem
57 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302512 Transaminase piruvica amino transferase de alanina - pesquisa e/ou dosagem
58 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 2,48 07/2026 Serviços Exame 40302547 Triglicerideos - pesquisa e/ou dosagem
59 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 1,74 07/2026 Serviços Exame 40302580 Ureia - pesquisa e/ou dosagem
60 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 8,28 07/2026 Serviços Exame 40302830 Vitamina D 25 HIDROXI, pesquisa e/ou dosagem Vitamina D3
61 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 3,72 07/2026 Serviços Exame 40304361 Hemograma com contagem de plaquetas ou fracoes eritrograma, leucograma, plaquet
62 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 8,3 07/2026 Serviços Exame 40308391 Proteina C reativa, quantitativa - pesquisa e/ou dosagem
63 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 2,48 07/2026 Serviços Exame 40311210 Rotina de urina caracteres fisicos, elementos anormais e sedimentoscopia
64 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 14,86 07/2026 Serviços Exame 40313328 Zinco - pesquisa e/ou dosagem
65 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 15,48 07/2026 Serviços Exame 40316270 Ferritina - pesquisa e/ou dosagem
66 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 25,76 07/2026 Serviços Exame 40316300 Globulina de ligacao de hormonios sexuais SHBG - pesquisa e/ou dosagem
67 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 6,81 07/2026 Serviços Exame 40316360 Insulina - pesquisa e/ou dosagem
68 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316467 T3 livre - pesquisa e/ou dosagem
69 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316491 T4 livre - pesquisa e/ou dosagem
70 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 18,58 07/2026 Serviços Exame 40316505 Testosterona livre - pesquisa e/ou dosagem
71 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 13,01 07/2026 Serviços Exame 40316513 Testosterona total - pesquisa e/ou dosagem
72 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316521 Tireoestimulante, hormonio TSH - pesquisa e/ou dosagem
73 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765930 '9750167003795586 LAERCIO WELTER MACHADO 1 0 - TITULAR 10080 10,53 07/2026 Serviços Exame 40316572 Vitamina B12 - pesquisa e/ou dosagem
74 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 541,31 07/2026 Mensalidade
75 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 16,68 07/2026 Serviços Exame 40805026 RX - Torax - 2 incidencias
76 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 77,72 07/2026 Serviços Exame 40808041 Mamografia digital bilateral com diretriz definida pela ANS - n 52
77 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 59,76 07/2026 Serviços Exame 40808130 Densitometria ossea - rotina: coluna e femur ou dois segmentos
78 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 38,52 07/2026 Serviços Exame 40901114 US - Mamas
79 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 78,49 07/2026 Serviços Exame 40901122 US - Abdome total abdome superior, rins, bexiga, aorta, veia cava inferior e ad
80 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 39,43 07/2026 Serviços Exame 40901203 US - Orgaos superficiais tireoide ou escroto ou penis ou cranio
81 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765912 '9750167003795608 ALESSANDRA APARECIDA WESTENBERGER MACHADO 2 1 - CONJUGE 10080 44,36 07/2026 Serviços Exame 40901300 US - Transvaginal utero, ovario, anexos e vagina
82 5855250-0 3151388 201924839 2778,08 2778,08 Aberto CHURRASCARIA BUFALO BRANCO LTDA - 81173460000113 765930 LAERCIO WELTER MACHADO - 838207 765913 '9750167003795616 MATHEUS WESTENBERGER MACHADO 2 10 - FILHO(A) 10080 129,61 07/2026 Mensalidade

View File

@ -0,0 +1,17 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
1006;JULIANA APARECIDA DA SILVA FOGACA;006.303.039-08;3755;01/04/2026;;;0;0;
1006;JULIANA APARECIDA DA SILVA FOGACA;006.303.039-08;3755;01/04/2026;BEATRIZ FOGACA HARTHMAN;096.075.699-03;0;0;
1006;VILSO RICARDO DE MELO;026.745.449-02;3755;01/04/2026;BENICIO HUBNER DE MELO;132.814.259-09;0;0;
1006;VILSO RICARDO DE MELO;026.745.449-02;3755;01/04/2026;;;0;0;
1006;VILSO RICARDO DE MELO;026.745.449-02;3755;01/04/2026;CAIRO HUBNER DE MELO;132.814.309-02;0;0;
1006;FELIPE ANDERSON RITTER;041.486.669-00;3755;01/04/2026;;;0;0;
1006;FELIPE ANDERSON RITTER;041.486.669-00;3755;01/04/2026;LETICIA GABRIELLY BIRKHEUER RITTER;126.888.299-20;0;0;
1006;FELIPE ANDERSON RITTER;041.486.669-00;3755;01/04/2026;LIGIA DOMINGUES VIEIRA BIRKHEUER;040.549.419-07;0;0;
1006;FELIPE ANDERSON RITTER;041.486.669-00;3755;01/04/2026;RIAN AUGUSTO BIRKHEUER RITTER;113.325.969-32;0;0;
1006;RODRIGO CORREA MONMA;048.592.079-47;3755;01/07/2026;HELOISA FERNANDES MOHMA;159.800.389-57;0;0;
1006;RODRIGO CORREA MONMA;048.592.079-47;3755;01/07/2026;MURILO FERNANDES MONMA;127.602.329-48;0;0;
1006;RODRIGO CORREA MONMA;048.592.079-47;3755;01/07/2026;TATIANE FERNANDES DA SILVA MONMA;054.124.379-90;0;0;
1006;RODRIGO CORREA MONMA;048.592.079-47;3755;01/07/2026;YURI FERNANDES MONMA;102.708.349-82;0;0;
1006;RODRIGO CORREA MONMA;048.592.079-47;3755;01/07/2026;;;0;0;
1006;GILMAR GILSON GARZELLA;474.476.560-20;3755;01/04/2026;INES TERESINHA MEGIER GARZELLA;478.014.500-78;0;0;
1006;GILMAR GILSON GARZELLA;474.476.560-20;3755;01/04/2026;;;0;0;
1 CODIGOEMPRESA NOMEFUNC CPFFUNC CODIGOOUTEMP DATAINICIAL NOMEDEPENDENTE CPFDEPENDENTE VALOREMPRESA VALOR DESCRICAO
2 1006 JULIANA APARECIDA DA SILVA FOGACA 006.303.039-08 3755 01/04/2026 0 0
3 1006 JULIANA APARECIDA DA SILVA FOGACA 006.303.039-08 3755 01/04/2026 BEATRIZ FOGACA HARTHMAN 096.075.699-03 0 0
4 1006 VILSO RICARDO DE MELO 026.745.449-02 3755 01/04/2026 BENICIO HUBNER DE MELO 132.814.259-09 0 0
5 1006 VILSO RICARDO DE MELO 026.745.449-02 3755 01/04/2026 0 0
6 1006 VILSO RICARDO DE MELO 026.745.449-02 3755 01/04/2026 CAIRO HUBNER DE MELO 132.814.309-02 0 0
7 1006 FELIPE ANDERSON RITTER 041.486.669-00 3755 01/04/2026 0 0
8 1006 FELIPE ANDERSON RITTER 041.486.669-00 3755 01/04/2026 LETICIA GABRIELLY BIRKHEUER RITTER 126.888.299-20 0 0
9 1006 FELIPE ANDERSON RITTER 041.486.669-00 3755 01/04/2026 LIGIA DOMINGUES VIEIRA BIRKHEUER 040.549.419-07 0 0
10 1006 FELIPE ANDERSON RITTER 041.486.669-00 3755 01/04/2026 RIAN AUGUSTO BIRKHEUER RITTER 113.325.969-32 0 0
11 1006 RODRIGO CORREA MONMA 048.592.079-47 3755 01/07/2026 HELOISA FERNANDES MOHMA 159.800.389-57 0 0
12 1006 RODRIGO CORREA MONMA 048.592.079-47 3755 01/07/2026 MURILO FERNANDES MONMA 127.602.329-48 0 0
13 1006 RODRIGO CORREA MONMA 048.592.079-47 3755 01/07/2026 TATIANE FERNANDES DA SILVA MONMA 054.124.379-90 0 0
14 1006 RODRIGO CORREA MONMA 048.592.079-47 3755 01/07/2026 YURI FERNANDES MONMA 102.708.349-82 0 0
15 1006 RODRIGO CORREA MONMA 048.592.079-47 3755 01/07/2026 0 0
16 1006 GILMAR GILSON GARZELLA 474.476.560-20 3755 01/04/2026 INES TERESINHA MEGIER GARZELLA 478.014.500-78 0 0
17 1006 GILMAR GILSON GARZELLA 474.476.560-20 3755 01/04/2026 0 0

View File

@ -0,0 +1,12 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
1084;CRISTIANA BARRETO LOPES;014.928.469-10;4723;01/08/2025;;;0;0;
1084;CRISTIANA BARRETO LOPES;014.928.469-10;4723;01/08/2025;ANNA CAROLINA LOPES WICHOSKI;092.056.569-76;0;0;
1084;CRISTIANA BARRETO LOPES;014.928.469-10;4723;01/08/2025;ANNA VICTORIA LOPES WICHOSKI;092.056.629-41;0;0;
1084;ISAN GUERRERO MORALES;025.746.839-00;4723;01/08/2025;;;0;0;
1084;SUZILAINE ZENATTI MEYER BEZERRA;032.900.149-32;4723;01/04/2026;JOELSON DA SILVA BEZERRA;023.089.899-80;0;0;
1084;SUZILAINE ZENATTI MEYER BEZERRA;032.900.149-32;4723;01/04/2026;;;0;0;
1084;SUZILAINE ZENATTI MEYER BEZERRA;032.900.149-32;4723;01/04/2026;JOAO LUCAS MEYER BEZERRA;118.021.609-14;0;0;
1084;LILIAN DE ARAUJO NUNEZ;073.890.749-90;4723;01/02/2026;HELOISA NUNES RAMBO;147.388.109-95;0;0;
1084;LILIAN DE ARAUJO NUNEZ;073.890.749-90;4723;01/02/2026;;;0;0;
1084;LILIAN DE ARAUJO NUNEZ;073.890.749-90;4723;01/02/2026;ALEX FERNANDO RAMBO;070.352.959-50;0;0;
1084;LILIAN DE ARAUJO NUNEZ;073.890.749-90;4723;01/02/2026;EUNICE FATIMA PADILHA RAMBO;524.044.399-87;0;0;
1 CODIGOEMPRESA NOMEFUNC CPFFUNC CODIGOOUTEMP DATAINICIAL NOMEDEPENDENTE CPFDEPENDENTE VALOREMPRESA VALOR DESCRICAO
2 1084 CRISTIANA BARRETO LOPES 014.928.469-10 4723 01/08/2025 0 0
3 1084 CRISTIANA BARRETO LOPES 014.928.469-10 4723 01/08/2025 ANNA CAROLINA LOPES WICHOSKI 092.056.569-76 0 0
4 1084 CRISTIANA BARRETO LOPES 014.928.469-10 4723 01/08/2025 ANNA VICTORIA LOPES WICHOSKI 092.056.629-41 0 0
5 1084 ISAN GUERRERO MORALES 025.746.839-00 4723 01/08/2025 0 0
6 1084 SUZILAINE ZENATTI MEYER BEZERRA 032.900.149-32 4723 01/04/2026 JOELSON DA SILVA BEZERRA 023.089.899-80 0 0
7 1084 SUZILAINE ZENATTI MEYER BEZERRA 032.900.149-32 4723 01/04/2026 0 0
8 1084 SUZILAINE ZENATTI MEYER BEZERRA 032.900.149-32 4723 01/04/2026 JOAO LUCAS MEYER BEZERRA 118.021.609-14 0 0
9 1084 LILIAN DE ARAUJO NUNEZ 073.890.749-90 4723 01/02/2026 HELOISA NUNES RAMBO 147.388.109-95 0 0
10 1084 LILIAN DE ARAUJO NUNEZ 073.890.749-90 4723 01/02/2026 0 0
11 1084 LILIAN DE ARAUJO NUNEZ 073.890.749-90 4723 01/02/2026 ALEX FERNANDO RAMBO 070.352.959-50 0 0
12 1084 LILIAN DE ARAUJO NUNEZ 073.890.749-90 4723 01/02/2026 EUNICE FATIMA PADILHA RAMBO 524.044.399-87 0 0

View File

@ -0,0 +1,4 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
128;LAERCIO WELTER MACHADO;968.229.109-72;5060;01/03/2026;;;0;0;
128;LAERCIO WELTER MACHADO;968.229.109-72;5060;01/03/2026;ALESSANDRA APARECIDA WESTENBERGER MACHADO;995.819.909-25;0;0;
128;LAERCIO WELTER MACHADO;968.229.109-72;5060;01/03/2026;MATHEUS WESTENBERGER MACHADO;104.587.539-20;0;0;
1 CODIGOEMPRESA NOMEFUNC CPFFUNC CODIGOOUTEMP DATAINICIAL NOMEDEPENDENTE CPFDEPENDENTE VALOREMPRESA VALOR DESCRICAO
2 128 LAERCIO WELTER MACHADO 968.229.109-72 5060 01/03/2026 0 0
3 128 LAERCIO WELTER MACHADO 968.229.109-72 5060 01/03/2026 ALESSANDRA APARECIDA WESTENBERGER MACHADO 995.819.909-25 0 0
4 128 LAERCIO WELTER MACHADO 968.229.109-72 5060 01/03/2026 MATHEUS WESTENBERGER MACHADO 104.587.539-20 0 0

View File

@ -0,0 +1,5 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
1601;ALINE PATRICIA RAMOS;076.350.759-85;4709;01/07/2026;;;0;0;
1601;DANTE HENRIQUE MUELLER;477.250.019-72;4709;01/07/2026;;;0;0;
1601;DANTE HENRIQUE MUELLER;477.250.019-72;4709;01/07/2026;CAIO PEREIRA MUELLER;053.273.449-16;0;0;
1601;DANTE HENRIQUE MUELLER;477.250.019-72;4709;01/07/2026;MARLENE PEREIRA MUELLER;466.162.920-53;0;0;
1 CODIGOEMPRESA NOMEFUNC CPFFUNC CODIGOOUTEMP DATAINICIAL NOMEDEPENDENTE CPFDEPENDENTE VALOREMPRESA VALOR DESCRICAO
2 1601 ALINE PATRICIA RAMOS 076.350.759-85 4709 01/07/2026 0 0
3 1601 DANTE HENRIQUE MUELLER 477.250.019-72 4709 01/07/2026 0 0
4 1601 DANTE HENRIQUE MUELLER 477.250.019-72 4709 01/07/2026 CAIO PEREIRA MUELLER 053.273.449-16 0 0
5 1601 DANTE HENRIQUE MUELLER 477.250.019-72 4709 01/07/2026 MARLENE PEREIRA MUELLER 466.162.920-53 0 0

View File

@ -0,0 +1,3 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
1604;BRUNO HENRIQUE BRAGA TONELLO;006.296.199-30;3755;01/01/2024;;;0;0;
1604;AMANDA GRACIELE CARVALHO DA SILVA;108.755.529-94;3755;01/04/2026;;;0;0;
1 CODIGOEMPRESA NOMEFUNC CPFFUNC CODIGOOUTEMP DATAINICIAL NOMEDEPENDENTE CPFDEPENDENTE VALOREMPRESA VALOR DESCRICAO
2 1604 BRUNO HENRIQUE BRAGA TONELLO 006.296.199-30 3755 01/01/2024 0 0
3 1604 AMANDA GRACIELE CARVALHO DA SILVA 108.755.529-94 3755 01/04/2026 0 0

View File

@ -0,0 +1,18 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
2028;YUNIOR CABRERA PEREZ;026.272.649-15;4723;01/08/2025;;;0;0;
2028;ERICKE PECORARI HOSSAIN;036.700.922-69;4723;01/08/2025;FLAVIA DOS REIS AHRENFELD HOSSAIN;101.759.839-84;0;0;
2028;ERICKE PECORARI HOSSAIN;036.700.922-69;4723;01/08/2025;;;0;0;
2028;RAFAEL TABORDA;082.004.769-44;4723;01/08/2025;;;0;0;
2028;LUIZ FERNANDO GONCALVES DA SILVA;082.193.739-11;4723;01/08/2025;TALITA ELISSAMA PIRES DA SILVA;092.513.939-40;0;0;
2028;LUIZ FERNANDO GONCALVES DA SILVA;082.193.739-11;4723;01/08/2025;;;0;0;
2028;LUIZ FERNANDO GONCALVES DA SILVA;082.193.739-11;4723;01/08/2025;CHRISTOPHER ALEXANDRE PIRES DA SILVA;140.577.939-09;0;0;
2028;LUIZ FERNANDO GONCALVES DA SILVA;082.193.739-11;4723;01/08/2025;MIGUEL FERNANDO PIRES DA SILVA;165.271.179-14;0;0;
2028;JANDIR MACHADO DA SILVA NETO;114.299.909-29;4723;01/08/2025;ANDRESSA DA SILVA PINHEIRO;106.505.229-40;0;0;
2028;JANDIR MACHADO DA SILVA NETO;114.299.909-29;4723;01/08/2025;;;0;0;
2028;HUMBERTO JOSE RODRIGUEZ SALAZAR;706.573.892-26;4723;01/07/2026;;;0;0;
2028;HUMBERTO JOSE RODRIGUEZ SALAZAR;706.573.892-26;4723;01/07/2026;GABRIELA ANDREINA MENDEZ GUERRA;802.379.739-52;0;0;
2028;ESTEBAN GABRIEL ESPINOLA;802.815.069-14;4723;01/01/2026;;;0;0;
2028;ESTEBAN GABRIEL ESPINOLA;802.815.069-14;4723;01/01/2026;MONICA RAFAELA SARASUA;122.834.911-85;0;0;
2028;ESTEBAN GABRIEL ESPINOLA;802.815.069-14;4723;01/01/2026;IAN GABRIEL ESPINOLA;125.171.311-47;0;0;
2028;REGINA FERNANDES;886.198.779-68;4723;01/08/2025;SOPHIA FERNANDES GONÇALVES;097.256.679-13;0;0;
2028;REGINA FERNANDES;886.198.779-68;4723;01/08/2025;;;0;0;
1 CODIGOEMPRESA NOMEFUNC CPFFUNC CODIGOOUTEMP DATAINICIAL NOMEDEPENDENTE CPFDEPENDENTE VALOREMPRESA VALOR DESCRICAO
2 2028 YUNIOR CABRERA PEREZ 026.272.649-15 4723 01/08/2025 0 0
3 2028 ERICKE PECORARI HOSSAIN 036.700.922-69 4723 01/08/2025 FLAVIA DOS REIS AHRENFELD HOSSAIN 101.759.839-84 0 0
4 2028 ERICKE PECORARI HOSSAIN 036.700.922-69 4723 01/08/2025 0 0
5 2028 RAFAEL TABORDA 082.004.769-44 4723 01/08/2025 0 0
6 2028 LUIZ FERNANDO GONCALVES DA SILVA 082.193.739-11 4723 01/08/2025 TALITA ELISSAMA PIRES DA SILVA 092.513.939-40 0 0
7 2028 LUIZ FERNANDO GONCALVES DA SILVA 082.193.739-11 4723 01/08/2025 0 0
8 2028 LUIZ FERNANDO GONCALVES DA SILVA 082.193.739-11 4723 01/08/2025 CHRISTOPHER ALEXANDRE PIRES DA SILVA 140.577.939-09 0 0
9 2028 LUIZ FERNANDO GONCALVES DA SILVA 082.193.739-11 4723 01/08/2025 MIGUEL FERNANDO PIRES DA SILVA 165.271.179-14 0 0
10 2028 JANDIR MACHADO DA SILVA NETO 114.299.909-29 4723 01/08/2025 ANDRESSA DA SILVA PINHEIRO 106.505.229-40 0 0
11 2028 JANDIR MACHADO DA SILVA NETO 114.299.909-29 4723 01/08/2025 0 0
12 2028 HUMBERTO JOSE RODRIGUEZ SALAZAR 706.573.892-26 4723 01/07/2026 0 0
13 2028 HUMBERTO JOSE RODRIGUEZ SALAZAR 706.573.892-26 4723 01/07/2026 GABRIELA ANDREINA MENDEZ GUERRA 802.379.739-52 0 0
14 2028 ESTEBAN GABRIEL ESPINOLA 802.815.069-14 4723 01/01/2026 0 0
15 2028 ESTEBAN GABRIEL ESPINOLA 802.815.069-14 4723 01/01/2026 MONICA RAFAELA SARASUA 122.834.911-85 0 0
16 2028 ESTEBAN GABRIEL ESPINOLA 802.815.069-14 4723 01/01/2026 IAN GABRIEL ESPINOLA 125.171.311-47 0 0
17 2028 REGINA FERNANDES 886.198.779-68 4723 01/08/2025 SOPHIA FERNANDES GONÇALVES 097.256.679-13 0 0
18 2028 REGINA FERNANDES 886.198.779-68 4723 01/08/2025 0 0

View File

@ -0,0 +1,8 @@
CODIGOEMPRESA;NOMEFUNC;CPFFUNC;CODIGOOUTEMP;DATAINICIAL;NOMEDEPENDENTE;CPFDEPENDENTE;VALOREMPRESA;VALOR;DESCRICAO
626;VANESSA LOPES GOMES;007.998.369-31;3755;01/05/2026;;;0;0;
626;ZAINAB MARIAM HAGE GONZALEZ;014.261.989-22;3755;01/06/2026;;;0;0;
626;BRUNA ALMEIDA BEVILAQUA;123.061.329-33;3755;01/07/2026;;;0;0;
626;JAMAL ABDEL FAYYAT;136.100.328-63;3755;01/07/2026;TAREK CASTRO FAYYAT;077.252.129-81;0;0;
626;JAMAL ABDEL FAYYAT;136.100.328-63;3755;01/07/2026;;;0;0;
626;JAMAL ABDEL FAYYAT;136.100.328-63;3755;01/07/2026;ELLEN LUCE RESENDE CASTRO FAYYAT;988.874.326-00;0;0;
626;NEURI DUARTE GARCIA;662.104.709-63;3755;01/05/2026;;;0;0;
Internal Server Error - De Paula Contadores — Git

Internal Server Error

Gitea Version: 1.22.3